Holy Cow. That's a fundamental concept that I did not get from the information available. Please add this into the README and wiki (or I will based on confirmations here) : CustomUrls generates one alias/URI per resource when a resource is saved. This does not use the OnPageNotFound event to redirect requests with a 301 header.
If that is accurate, can you clarify what this actually does do? From the introductory text: This extra allows you to define custom alias or URI patterns for your resources. It supports translit and Redirector packages. You can build your patterns from resource fields, TV, snippets and output filters and set some constraints like you'd do with custom forms. For example, with CustomURLs you can add the resource's ID or publish month in the aliases of all resources or just for ones whose parent = 1 or template = 1.
From that, should I understand that this is intended to modify the alias value for resources? That doesn't look like what the code is doing. Please help me to understand what to expect from this extra so that I can properly use it, and I will be happy to collaborate to ensure that's communicated in the notes. ( Unless I'm the only one who doesn't "get it". )
Yes this package modifies the alias/URI value for resources.
I created this package because I wanted to add automatically resources ID in their alias and so make them unique and make my clients life easier ! But maybe the description of this package is confused. I will clarify that in wiki, README and code.
Thanks to this extra, for example, I also can create folders in my resource tree that not appear in childrens alias. It can be usefull for classifying resources.
About the redirect code, sincere thanks for that, but that q=alias isn't elegant.
You're right, it was just a quick proposition. Here I replaced alias detection with code from Redirector package. More elegant I think.
<?php
// Get the URI
$search = $_SERVER['REQUEST_URI'];
$baseUrl = $modx->getOption('base_url', null, MODX_BASE_URL);
if (!empty($baseUrl) && $baseUrl != '/' && $baseUrl != ' ') {
$search = str_replace($baseUrl,'',$search);
}
// Remove the extension
$uri = preg_replace('#(/|(\..*))$#', '', $search);
// Search a resource with similar URI
$c = $modx->newQuery('modResource');
$c->where(array('uri:LIKE' => $uri.'%'));
$c->select(array('id'));
$resource = $modx->getObject('modResource', $c);
// If a such resource exists we redirect user to
if ($resource) {
$modx->sendRedirect($modx->makeUrl($resource->get('id')),array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
}
Here is what I thought CustomUrls did. Maybe the code can be forked into another extra that matches this apparently incorrect understanding.
- Set patterns like:
[[+cu.parent_uri]]/[[+alias]]
[[+cu.parent_uri]]/[[+alias]].html
[[MySnippet? &id=`[[+id]]`]]
- On Generate, each resource is queried. The alias, ID, and other values are integrated into each pattern in a loop, and a new alias is stored for each pattern. That's X resources times Y patterns = Z new aliases.
- With the above patterns we might get:
products/prod1
products/prod1.html
services/serv1
services/serv1.html
- Based on snippet code which uses the ID to read each resource and process TV's or metadata, the snippet might return:
/smartphones/lg/p999 for the product, or
/software/development/webservices for the service
- With the cross-reference table generated, on every resource update, the ID/alias is used to regenerate the cross-references for the resource, again with one new alias for each pattern.
- On page request and OnPageNotFound, the table is queried with whatever the user specified. A match returns the ID.
- As to what happens here:
- Perhaps a 301 redirect is made to /alias or ?q=id or some preferred/canonical reference.
- Or perhaps a transparent URL rewrite is performed and resource 'id' is returned without changing the address bar.
- To create a new pattern for the entire site, use the config page and click the Generate button to refresh the xref table.
OK, so it does not work like that. (?) But it sure seems close. Where is that wrong? And can you please correct it so that we can all understand exactly how CustomUrl does work?
Thank you very much!!
For performances purpose, I prefer to generate alias/URI on resource save once and then letting MODx handle resources instead of letting MODx search a resource that doesn't exist, call a OnPageNotFound plugin, and once again get the right resource from DB. So I don't think I will update this package in that way but you're free to forked it and develop your own MODx extra. But in your case a 404 plugin should do the trick I think.