I'm trying to create an action that matches all URLs except for the /admin/ ones. I also want to capture the URL that was entered, but so far I can only do the first bit.
get %r{^(?!/admin/.*$)}
That's what I've got so far. This will make sure I get all URLs except admin, but then how do I capture what the URL was?
aha!
Figured it out :)
get %r{^(?!/admin/.*$)(.*)} do |content|
You can find the current path in request.path_info.
Related
I'm using Sinatra and the shotgun server.
When I type in http://localhost:9393/tickets, my page loads as expected. But, with an extra "/" on the end, Sinatra suggests that I add
get '/tickets/' do
How do I get the server to accept the extra "/" without creating the extra route?
The information in Sinatra's "How do I make the trailing slash optional?" section looks useful, but this means I would need to add this code to every single route.
Is there an easier or more standard way to do that?
My route is set up as
get '/tickets' do
It looks like the FAQ doesn't mention an option that was added in 2017 (https://github.com/sinatra/sinatra/pull/1273/commits/2445a4994468aabe627f106341af79bfff24451e)
Put this in the same scope where you are defining your routes:
set :strict_paths, false
With this, Sinatra will treat /tickets/ as if it were /tickets so you don't need to add /? to all your paths
This question is actually bigger than it appears at first glance. Following the advice in "How do I make the trailing slash optional?" does solve the problem, but:
it requires you to modify all existing routes, and
it creates a "duplicate content" problem, where identical content is served from multiple URLs.
Both of these issues are solvable but I believe a cleaner solution is to create a redirect for all non-root URLs that end with a /. This can easily be done by adding Sinatra's before filter into the existing application controller:
before '/*/' do
redirect request.path_info.chomp('/')
end
get '/tickets' do
…
end
After that, your existing /tickets route will work as it did before, but now all requests to /tickets/ will be redirected to /tickets before being processed as normal.
Thus, the application will respond on both /ticket and /tickets/ endpoints without you having to change any of the existing routes.
PS: Redirecting the root URL (eg: http://localhost:9393/ → http://localhost:9393) will create an infinite loop, so you definitely don't want to do that.
i'm trying to make this code snippet from the sinatra tutorial work so that I can set some routes based on regex matching. it doesn't seem to be working and I'm copy pasting direct from the tutorial, any ideas on what i'm missing. make the assumption that my sinatra app is working and i have other correctly structured GET routes working so I'm unclear why a direct copy past like this doesn't work.
get %r{/hello/([\w]+)} do
"Hello, #{params[:captures].first}!"
end
should correct map a route for http://0.0.0.0:4567/hello but is routing to a 'sinatra doesn't know this ditty' error message.
Thks.
%r{/hello/([\w]+)} doesn't match /hello at all. Your regex requires a slash and another string, but your path doesn't include that.
That route would match /hello/there but not /hello or even /hello/.
And given that you are looking at the captures, you probably don't even want this to work with /hello at all since that capture would be nil and who want to say hello to nil?
I have been looking around the Tank auth code to see how things are done, but it seems a little confusing to find out how to change the path of the default login.
I wanted to change it to groups/login or users/sign_in, but that wasn't an easy task. I'm wondering whether I should change that from the routing file or any other file.
Any idea how to get around with this little issue?
I'm wondering whether I should change that from the routing file
Yes, that's exactly what URI Routing is for:
$route['your/desired/url'] = 'auth/login';
If you need to kill the old URL for some reason, you can set it to something empty:
$route['auth/login'] = FALSE;
Unfortunately, the Tank Auth login url is assumed to be auth/login, and there are several redirects that must be edited. I recommend adding a custom config setting to config/tank_auth.php:
$config['login_url'] = 'your/desired/url';
Then replace all occurrences of redirect('/auth/login') with:
redirect($this->config->item('login_url', 'tank_auth'));
in the Auth controller and anywhere else it appears.
Why not just change the name of the controller from 'Auth' to whatever you want? Seems the shortest route to me.
I was just wondering if it is possible to ignore the last URI segment of my application via either mod_rewrite or CodeIgniter. I don't want a redirect away or a remove the URI segment. I just want my app to not know it exists. So in the browser the client will see:
http://example.com/keep/keep/ignore/
but the app is only aware of:
http://example.com/keep/keep/
The idea is, if JavaScript detects /ignore/ in the URI, it will trigger an action.
/ignore/ may appear as 1st, 2nd, 3rd or 4th segment, but will only ever appear as the final one and may sometimes not appear at all.
I found some info online about ignoring sub-directories with mod-rewrite, but none of them really work like this.
**
Incase any CodeIgniters suggest passing it as an unused extra parameter to my method - The app has far too many controllers and far too many wildcard routes for this to work site wide.
I think a mod_rewrite solution would be best if possible. If not, perhaps it can be done with a CodeIgniter pre-controller hook or something, but I'm not sure how that would work.
EDIT: How I got it to work
For anyone else who would ever like to know the same thing - in the end I overwrote _explode_segments() in MY_URI to not include this segment.
With the URI class you can check and detect what URI's are and what they have.
$this->uri->segment(n)
Check out the user guide: http://codeigniter.com/user_guide/libraries/uri.html
I'm having a little trouble with a CodeIgniter route when there is a query (stuff after the ?) in the URI. I know it is good practice to replace queries with routes in CI, but I'm importing in a premade messageboard that already does everything with queries. This is my route:
$route['messageboard/:any'] = "messageboard/index";
Any in this case refers to a script name. So if it's messageboard/admin.php, I have it load a view that loads my premade messageboard's script "admin.php". It's working just fine if I do messageboard/admin.php. It does fine if I do messageboard/admin.php?. If I put a parameter into the query, however, the route won't correctly send the user to the messageboard controller, and instead sends them to a 404. Does anyone have any ideas on how to make this work? I would be eternally grateful. Thanks!
Okay guys, I solved it. I needed to change three things. The first was mtvee's suggestion, which lets it read query strings. The second one you're going to want to change the $config['permitted_uri_chars'] in the config file to include an equals sign, since it starts off disabled and all query strings will be of the for ?a=34 or something like that. The third is you need to go to $config['uri_protocol'] and change it from AUTO to PATH_INFO. Once I did those, it worked.
I'm sure the syntax is:
$route['messageboard/(:any)'] = "messageboard/index"; //<-- notice brackets
and not
$route['messageboard/:any'] = "messageboard/index";
I believe CI doesn't do GET out of the box. Check out Enabling Query Strings here http://ellislab.com/codeigniter/user-guide/general/urls.html