Jump to content

ProcessPermalink


Nico Knoll
 Share

Recommended Posts

Hi,

today I want to introduce my biggest and most powerful module until today: ProcessPermalink.

The main function is to change URLs of pages so that you can customize the pages URLs (e.g.: http://example.com/article/abc/ -> http://example.com/2011/10/10/abc/). You can set a separate URL formats for each template under "Your Template -> URLS -> Permalink Format". For this, you can use the following placeholders (I'll add some more in the future): %name%, %author%, %id%, %year%, %month%, %day%, %hour%, %minute% and %second%.

It's not perfect right now but it's working. Unfortunately you have to do two core hacks to make some core functions hookable:

  • Change "buildEditFormURLs" to "___buildEditFormURLs" in line 916 of "wire/modules/Process/ProcessTemplate/ProcessTemplate.module"
  • Change "path" to "___path" in line 865 of "wire/core/Page.php"

Another problem is that you have to add a URL format to every existing template and to every template you'll create in the future.

And something that will probably be missed right now is %parents% (and maybe something like %default%) but I'm working on it.

But I would be happy if you could try it out and report errors to me so that I can optimize it.

You can download it here: https://github.com/NicoKnoll/ProcessPermalink

Hope it will work for you!

Greets,

Nico

post-5023-132614281928_thumb.png

  • Like 1
Link to comment
Share on other sites

Nice drive you have Nico! I can see your need for this module, but I personally would try to keep urls in sync with page tree. Part of the pw simplicity comes from pagetree and url sync, when compared to bucket based systems like ee and Drupal. But if the need comes to have different url schema, I will definitely use this.

Link to comment
Share on other sites

Nice work Nico! I'll get those additional hooks put into the dev branch. The only one I'm not sure I can do is the Page::path hook, because that one is called so often that it's possible that making it hookable could introduce more overhead than we'd want. But maybe there's another way around it.

I'm with Antti in that I'm not sure I totally understand the drive to have alternate URLs outside of the site's structure. Primarily because it makes me worry about duplicate content penalties and inconsistent offsite/incoming links to the same content, and how that dilutes pagerank. But we all have different needs and if you've had the need for this type of setup then I know others will as well. I think you've done a nice job building this module and the code quality looks good. I only have a few suggestions:

1. The first line of the last method in your class looks like this:

$page = $this->pages->get($_GET['id']); 

That's not desirable because it's sending unfiltered input to $pages->get(). Since $pages->get() can deal various kinds of input (selectors, integers, etc.) you want to make sure you are giving it the right thing, so in your case I would do this (typecast to integer):

$page = $this->pages->get((int) $_GET['id']); 

Or better, yet, use PW's input class:

$page = $this->pages->get((int) $this->input->get->id); 

However, you may not need to do this at all since ProcessPageEdit will already have a copy of the page that you can use:

<?php
if($this->process == 'ProcessPageEdit') {
    $page = $this->process->getPage(); 
}

getPage() is a helper method I added to ProcessPageEdit back when first building the PageEdit process, primarily so hooks could see what Page it was editing. So this is exactly the sort of situation that it's there for, if you want to use it.

2. Stepping back a bit, why is this a 'Process' module? It looks to me like it should actually be a regular module because I don't see any execute() method. A Process module is one that is assigned to a Page (usually an admin page) and executes some actions that generate output for the page being viewed. This module hooks into other things to change their behavior, rather than generating it's own output. I think you may want to change it to extend 'WireData' rather than 'Process' and perhaps rename to 'PagePermalink' or something like that?

3. You may not need your own pageNotFound() method? ProcessWire already has one that is called whenever you throw a Wire404Exception, i.e.

throw new Wire404Exception(); 
Link to comment
Share on other sites

My problem is that I have like 300 article pages. And I have some static pages. So if I would have each page as child of "/" it would be hard to find to the static pages.

So I created to different pages as parents ("pages" and "article") but I don't wanted to see "article" or "pages" in the url.

To 2.: If I'm creating a module I often don't really know how I should name it (I know, we had this already but I forget where) and I'm not sure what kind of class I should use for "extends" or "implements" so I'm normally just using something that works :)

To 1. and 3.: I'll improve this in the next update :)

Link to comment
Share on other sites

It sounds like you've got everything is living off the root namespace, at least on the front end? That can only scale so far, unless you are using page ID as a url segment or something like that. Though it may be fine for the scale of a blog, but it's something to be careful with if the site gets really big. :) I take it that on your back end, the entries are living at /articles/ or /entries/ or something like that; and you are loading the entry with an $input->urlSegment1 from your homepage? This seems like a fine way to go, though it is treating the site as a bucket rather than a tree. A more structured way of doing it would be to have several categories and then place each entry under a category (or at least, primary category if multiple) and make that structure consistent both on the back and front-end. But you set the rules and PW is there to adapt, so don't take this as a suggestion to change anything. But what I would recommend is to make it clear to Google what you are doing (to avoid dup content penalties): add a 'canonical' meta tag to the pages in your root-level namespace so that they map to your permalinks or actual page URL. If your date-based links are the ones you consider permanent, then make sure that if the page is rendered at it's actual URL (/article/some-page/) then it also outputs with the canonical meta tag. That is just a way to tell Google what you are doing and that it should consider them the same pages, even if they live at different URLs.

Link to comment
Share on other sites

The category thing isn't possible because some articles got more than one category. So I've created a 3 third child of home called "categories" and made every category a subpage of "categories". And if you're editing a article you can add categories with an page tree :D

Link to comment
Share on other sites

I think it's totally fine to go with the bucket approach here and so not suggesting you change it. I'd use the bucket approach for blog entries too (unless I was a really prolific writer). :) But if there are times when you want to build a structure around categories, and there can be multiple categories, then you can still do this with a tree. You just have to think in terms of primary category and secondary categories. The primary category becomes the parent, and the secondary categories become page references to the siblings of the parent. Even though there is a structure there, you can still pull them all out of a bucket when you want to by using $categoriesParent->find('...') or $pages->find('template=entry, ...');

Link to comment
Share on other sites

  • 2 weeks later...
  • 8 months later...

Nico,

ProcessPermalink module doesn't work with ProcessWire 2.2. I've made a core hack to buildEditFormURLs function (so permalink settings can appear in template url settings) but now every link goes to root url, on the front side and in the admin.

Can you fix this please?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...