Hide FW/1 actions without controller method (view only) - coldfusion

Currently I am using "partials" concept in my FW/1 views: these chunks of layout that can be re-used by different views. They are prefixed with underscore for easier maintenance, but unlike the CFWheels these still can be used as implicit views which is not very good.
For example, there's a directory structure:
/views/member/_user.cfm
/views/member/profile.cfm
/views/member/register.cfm
This way actual user form is in the _user.cfm and can be included to the two others using #view('member/_user')#.
What I want is to prevent access to the pages like member._user on the website.
One solution is to create the _user method in member.cfc controller and redirect user somewhere. But creating such methods for each partial is kinda inefficient approach.
Alternative to this would be parsing the rc.action in before and checking if there's underscore in the prefix, but I'm not sure this is clean solution.
Is it possible to disable the action (throw 404) if there's no corresponding method in controller? Or maybe there are some framework events/flags which would allow me to handle "missing method" situation in before?
Thank you.

You can create a method in a controller that checks rc.action to see if the item part starts with a _ and redirects elsewhere (or throws an error, or whatever you want to do). Then call this method using controller() function in your setupRequest() method in Application.cfc.
For example, I have a controllers/security.cfc controller with checkItem() method as follows:
function checkItem( rc ) {
//check if restricted item hss been requested and redirect to main.default
if ( left(variables.fw.getItem(), 1) eq "_" ) {
variables.fw.redirect('main');
}
}
And call it in setupRequest() in Application.cfc:
function setupRequest() {
//controller( 'security.authorize' );
controller( 'security.checkItem' );
}
This way it is automatically called on every request - no need to define a separate method for each _item in controllers.

The easiest way to do this is to put them in a folder that is not in the web root. Therefore they are not web accessible. Then use a ColdFusion mapping to make them available to ColdFusion.
Make sense?

You could use mod_rewrite to detect URLs containing /_ and block/redirect as appropriate.
For example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/\w+/_
RewriteRule ^.* /error/404 [L]
The first RewriteCond makes sure that the file does not exist - so if you have a real file /css/_default.css any requests for that will fail this condition and not redirect.
The second RewriteCond accepts any alphanumeric for the first segment, then continues if there is a _ at the start of the second segment. (It's not necessary to match the entire URI, just the start is enough.)
Finally, the RewriteRule is applied only if both conditions were true, but matches all URLs, and performs a server-side redirect to /error/404 - you can update that part as appropriate. (The [L] flag tells mod_rewrite not to attempt any further rewrites.)

OK, since there's no answer which I've expected (which is fine), here's one more approach which I am using for email templates already.
In the /views/emails/ all the views are email templates which do not have actions, but invoked only like this:
local.body = variables.fw.view("emails/registration_confirmation", local.attrs);
local.template = variables.fw.view("emails/default", {body = local.body});
Where registration_confirmation.cfm is template for specific email body and default.cfm (could call it differently) is email template itself.
To prevent the problem I've described in question controller emails.cfc looks like this:
component extends="components.helpers.controller" {
public void function before(required struct rc) {
variables.fw.redirect("user.forbidden");
}
}
I guess it would be possible to create one more such controller partials.cfc and keep all views in /views/partials/.
But this is my first real-life FW/1 project and I came with idea too late to refactor so many views (1), plus I think having partials in same directory is worse from maintenance point of view, than having them where it makes sense for them (2).
These are two reasons why I've asked this question.

Related

Doing math on Apache RedirectMatch for WordPress

This is similar to this, but I am not using the Perl module.
Problem
I am using WordPress 4.3 and I need to add a number like 1122000 to post_id for permalinks structure.
This is what I have as default URL structure:
mysite.com/?post_type=orders&p=139
and this is desired permalink structure:
mysite.com/orders/1122139
Please note that we can't just concatenate 1122 into the post_id as post_id may exceed 999 at future.
My efforts
In my first try I used add_rewrite_rule function:
function my_rewrite_basic() {
add_rewrite_rule( '^orders/1122([0-9]+)/?', 'index.php?post_type=orders&p=$matches[1]', 'top');
}
add_action('init', 'my_rewrite_basic');
Which works only if id is lower than 1000.
In my second try I directly used Apache RedirectMatch like this:
RedirectMatch 301 ^/orders/(\d+) /?post_type=orders&p=($1-1122000)
in .htaccess file with no success.
Is there another way to implement a 7 digit serial number based on post_id?
Regex does not allow you to do math. RewriteRule doesn't allow you do math either.
You should look into modifying the data in the database. You could add that number to the post id in the database, while taking care that no foreign key constrainst are broken (That means, either you configure explicit foreign keys with on update cascade option, or you update manually every field that contains a reference to the post id.
Another option would be to write a routing plugin for wordpress, which would allow you to enforce any rewrite rules you liked.

adding parameter to wordpress url without query string

i want to have parameter in friendly urls way, have done it with query string but this is not what i want
below is my link
http://www.example.org/category-name/sub-category/post-name-goes-here
and want to have link in template like this
http://www.example.org/category-name/sub-category/post-name-goes-here/parameter
it should still load the same single page but with parameter so i can use condition in single page template
how i can ignore this using rewrite rule or any other method?
You will need to add a rewrite rule so it doesnt try and "solve" the url address using its standard function .
See my previous answers here:
Add "custom page" without page
WordPress Rewrite based on form hidden field
you can pretty much add anything to the url after that.

Symfony routing - How can I implement a rule that redirects any URL that matches a specific pattern?

Let's say I want any URLs that contains the word "potatoes" to be redirected to http://www.mysite.com/home
Is there any smart routing rule that can achieve that ?
Or should I use a filter ?
PS: I'm using Symfony 1.4
I think this probably would be possible by writing your own sfRoute class, and try to override the matchesUrl() function. But this requires quite deep knowledge of symfony.
Probably it's more easy just to add an .htaccess rewrite rule, something like this (not tested):
RewriteRule ^(.*)potatoes(.*)$ index.php/home [R=301]
This of course only works if your webserver is Apache, otherwise you have to find an equivalent for your webserver.

Django catch-all URL without breaking APPEND_SLASH

I have an entry in my urls.py that acts as a catch-all which loads a simple view if it finds an appropriate page in the database. The problem with this approach is that the URL solver will then never fail, meaning that the APPEND_SLASH functionality won't kick in - which I need.
I'd rather not have to resort to adding a prefix to the static page URLs to stop it being a catch-all. I do know about flatpages, which uses a 404 hook rather than an entry in urls.py, and I had kinda hoped to avoid having to use it, but I guess this problem might be exactly the kind of reason why one would use it.
Any way round this problem or should I just give in and use flatpages?
Make sure that your catch-all URL pattern has a slash at the end, and that the pattern is the last in your URLconf. If the catch-all pattern doesn't end with a slash, then it will match stray URLs before the middleware tries appending a slash.
For example, use r'^.*/$' instead of r'^.*' as your last pattern.
To do the same, but pass the url to the view as a named argument, use r'^(?P<url>.*)/$'.
The statement if it finds an appropriate static page in the database seems like your static pages are not quite static so, you either pass your links through urls.py (just like you do now), or you extract those pages from the DB, put them in a directory and configure that directory as one for serving static files

Recursive URL Patterns CMS Style

Whenever I learn a new language/framework, I always make a content management system...
I'm learning Python & Django and I'm stuck with making a URL pattern that will pick the right page.
For example, for a single-level URL pattern, I have:
url(r'^(?P<segment>[-\w]+)/$', views.page_by_slug, name='pg_slug'),
Which works great for urls like:
http://localhost:8000/page/
Now, I'm not sure if I can get Django's URL system to bring back a list of slugs ala:
http://localhost:8000/parent/child/grandchild/
would return parent, child, grandchild.
So is this something that Django does already? Or do I modify my original URL pattern to allow slashes and extract the URL data there?
Thanks for the help in advance.
That's because your regular expression does not allow middle '/' characters. Recursive definition of url segments pattern may be possible, but anyway it would be passed as a chunk to your view function.
Try this
url(r'^(?P<segments>[-/\w]+)/$', views.page_by_slug, name='pg_slug'),
and split segments argument passed to page_by_slug() by '/', then you will get ['parent', 'child', 'grandchild']. I'm not sure how you've organized the page model, but if it is not much sophiscated, consider using or improving flatpages package that is already included in Django.
Note that if you have other kind of urls that does not indicate user-generated pages but system's own pages, you should put them before the pattern you listed because Django's url matching mechanism follows the given order.