How to make all pages within a folder other than /pages handled by High Voltage? #47

Closed
samueller opened this Issue Oct 12, 2012 · 14 comments

Projects

None yet

4 participants

I haven't been able to get pages within a folder other than /pages to be handled by High Voltage. For example, I can get the following to work (thanks to jferris on my previous issue):
match '/company/about' => 'high_voltage/pages#show', :id => 'company/about'

That will load the app/views/pages/company/about.html.erb file when the http://example.com/company/about URL is requested.

Perfect, except I want all pages in the /company/ folder to be handled this way. I tried this route:
match '/*id' => 'high_voltage/pages#show', :constraints => { id: /company\/.*/ }

But it seems constraints in rails don't work if there's a wildcard in the route. So everything matches the above route and the constraints are ignored.

zben commented Oct 12, 2012

The key is to make sure your company/about is under pages/ directory. you can override this name by reassigning HighVoltage.content_path. HighVoltage needs to assume a fixed root directory. You are free to nest as many layers of views as you want within it. so you can have

pages/
   company/
      about.html.erb
   people/
      team.html.erb

And they will all work automatically.

I have tried

match '/*id' => 'high_voltage/pages#show', :constraints => { id: /company\/.*/ }

It is working for me. In fact, all you need is

match '/*id' => 'high_voltage/pages#show'

The constraint is not necessary for high_voltage to find the correct view to render. If you are just matching "/*id", put it at the bottom of your routes.rb so it does not intercept other routes.

@zben zben was assigned Oct 12, 2012

Yes, I thought about putting that at the end of my routes.rb file, but I have another catchall. Is there a way that HighVoltage can redirect to another page if the route is not found? At least display a custom 404 page?

gosseti commented Oct 19, 2012

How would I need to modify the code below to get routes working for posts and pages?

match '/*id' => 'pages#show', :as => :static_page, :via => :get, :format => false
get '/:slug', :to => 'posts#show', :as => 'post'

It’s currently responding with: No such page: example-post.

Collaborator
harlow commented Oct 23, 2012

@samueller @gosseti the following code sample will look for static content in the pages directory and serve it up if theres a match; if the page doesn't exist it will continue through the rest of the routes.

Let me know if this code works for you (note if you are using haml, or something other than pages directory a few things will need to change).

P.S. don't forget to restart the rails server once the constraint file has been added.

# config/routes.rb
match '/*id' => 'high_voltage/pages#show', :constraints => HighVoltageConstraint

Depending on where you choose to put this file in your application you may need to add the directory to the auto-load path in config/application.rb

# lib/high_voltage_constraint.rb
class HighVoltageConstraint
  def self.matches?(request)
    File.exist? file_path(request.path)
  end

  private

  def self.file_path(view)
    high_voltage_views_dir.to_s.concat("#{view}.html.erb")
  end

  def self.high_voltage_views_dir
    Rails.root.join('app', 'views', 'pages')
  end
end

Thank you @harlow. This is a good solution for my needs. HighVoltageConstraint should be included in the high_voltage gem.

Collaborator
harlow commented Oct 23, 2012

@samueller glad this works for you. Will look into creating a generalized version for the next release of the gem.

@harlow if I copy your code exactly, I get:

NameError

uninitialized constant HighVoltageConstraint

So I added .new after HighVoltageConstraint in config/routes/rb as per the official rails guide docs. But then the constraint isn't even called at all:

  class HighVoltageConstraint
    def self.matches?(request)
      puts "this doesn't get output"
      File.exist? file_path(request.path)
    end

    private methods...

It's the same as if I commented out the high_voltage route in routes.rb.

I also tried def matches? instead of def self.matches? as shown in the rales guide docs:
http://guides.rubyonrails.org/routing.html#advanced-constraints

gosseti commented Oct 23, 2012

@samueller If you go to config/application.rb, and find the following line:

# config.autoload_paths += %W(#{config.root}/extras)

Change it to:

config.autoload_paths += %W(#{config.root}/lib)

This will then tell Rails to look in that directory to find the custom constraint class.

gosseti commented Oct 23, 2012

@harlow Many thanks for the solution on this one.

Fiddled with this for a while. Finally got it to work. @gosseti you're right the HighVoltage class wasn't being loaded, strange why I wasn't getting errors with HighVoltageConstraint.new, just wasn't taking into effect. I simply had to do a require 'high_voltage_constraint' at the top of routes.rb (or the way above with autoloading). But I still had to pass an object HighVoltageConstraint.new as opposed to the class HighVoltageConstraint to the match method. Which means I had to remove self. in front of the method names in HighVoltageConstraint.

Collaborator
harlow commented Oct 26, 2012

@gosseti @samueller Thanks for working with me on this. We will support root routes with a constraint in the next release.

@harlow harlow closed this Oct 26, 2012

@harlow - I noticed a new release came out, does this support root routes with a constraint? For some reason, Rails 3.2.9 and Heroku no longer see my static page constraint class (though it works fine locally):
http://stackoverflow.com/questions/13386828/heroku-website-crashes-with-rails-3-2-9-and-route-constraint

Collaborator
harlow commented Nov 14, 2012

@samueller thanks for the note. Root route constraints were indeed added in the last release -- didn't try running with 3.2.9 on Heroku so I'll put together a dummy app and see if I can replicate the error.

https://github.com/thoughtbot/high_voltage#enabling-root-domain-routes

Collaborator
harlow commented Nov 16, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment