middleman / middleman

Hand-crafted frontend development
https://middlemanapp.com
MIT License
7.05k stars 748 forks source link

Generating dynamic pages from partials #1527

Closed michaelparenteau closed 9 years ago

michaelparenteau commented 9 years ago

I am working on some cool stuff using Middleman v. 4.0.0.beta.2 and am trying to do some fancy stuff to watch a directory in source called "components" which is a place to put partials to be reused in prototypes with a layout context. I want to be able to test the components in isolation on their own page and could create a file for each partial... but that seems like it could be automated via the proxy function in config.rb.

Here is what I have to do this:

# In config.rb
Dir["source/components/**/_*.haml"].each do |raw_name|
  partial_name = raw_name.sub(/source\//,"").sub(/_(.*)\.haml/,'\1')
  component_name = raw_name.gsub(/source\/(.*)\/_(.*).haml/,'/\1/\2.html')
  proxy component_name, "/component_template.html", :locals => { :partial_name => partial_name }, :ignore => true
end

When I start the server, my components are rendering to their expected route. During development however, the routes yield a "File Not Found /components/foo". Restart the server and boom. It works.

What am I missing here? Is there already a way to do this and I missed it in the docs or am I just doing something silly?

tdreyno commented 9 years ago

Can you poke around http://localhost:4567/__middleman and see what the sitemap thinks has been generated?

So, you're saying it works the second time, but not the first?

This may just be a bug in v4. Proxies used to directly edit the sitemap, now they produce little ProxyDescriptor records which are merged into the sitemap in a different phase.

We also have some new "live collection" stuff where changing resources or data will re-run code dependent on that, such as data.people.each. I'm wondering if it make sense to have a generic hook for this so your above code would be "live". That is, adding a new .haml would not require a server restart to build the route.

michaelparenteau commented 9 years ago

Ok yeah, with the server running, I create _foo.haml inside the components dir like shown above. The block to proxy each _partial.haml file in the directory to /components/partial is in config.rb as listed in earlier comment. I try to visit the URL to the component's page and I get a "File Not Found".. and then when I visit http://localhost:4567/__middleman I do not see the file (foo) listed in the components dir or anywhere in the sitemap.

Then when I restart the server the components/foo url is visible. And the sitemap shows:

foo.html
  Path          components/foo.html
  Build Path    components/foo/index.html
  URL           /components/foo/
  Source File   source/component_template.html.haml
  Locals        partial_name

So it seems that everything is working except that like you describe above, the above code in config.rb is not "live". Proxies are generated when the files are created and then server restarted. But during development... they are not found.

tdreyno commented 9 years ago

Just pushed an update (which resulted in some nice code simplification too). Try this on github master:

live {
  Dir["source/components/**/_*.haml"]
}.each do |raw_name|
  partial_name = raw_name.sub(/source\//,"").sub(/_(.*)\.haml/,'\1')
  component_name = raw_name.gsub(/source\/(.*)\/_(.*).haml/,'/\1/\2.html')
  proxy component_name, "/component_template.html", :locals => { :partial_name => partial_name }, :ignore => true
end