Example: Changing a Page's Location Based on its Date

Here's a practical example. Let's say on a website you'd like to create blog posts and have them structured at a particular URL scheme based on date. So, if you added a blog entry named "Hello World" it would be found at

/blog/2016/03/hello-world

Rather than just /blog/hello-world. Yes, you could set a custom canonical URL, but why not just use page events to automatically place the post at the proper location? Here's how you might go about it:

First, we'll create an instance of a custom handler class. This handler class will be responsible for placing the post in the correct area of the site. (Note: describing how this works is outside the scope of this document. This is simply about showing how we can trigger the use of this class using custom application events.)

$handler = new \Path\To\My\Custom\PageHandler();

Now, we hook into three separate events:

\Concrete\Core\Support\Facade\Events::addListener('on_page_type_publish', function($event) use ($handler) {
    $page = $event->getPageObject();
    if ($page->getPageTypeHandle() == 'blog_entry') {
        $handler->placePost($page);
    }
});
\Concrete\Core\Support\Facade\Events::addListener('on_page_version_approve', function($event) use ($handler) {
    $page = $event->getPageObject();
    if ($page->getPageTypeHandle() == 'blog_entry' && $page->isPageDraft()) {
        $handler->placePost($page);
    }
});
\Concrete\Core\Support\Facade\Events::addListener('on_page_move', function($event) use ($handler) {
    $page = $event->getPageObject();
    if ($page->getPageTypeHandle() == 'blog_entry') {
        $parent = $event->getOldParentPageObject();
        $handler->cleanPostParent($parent);
    }
});

This is pretty self-explanatory. The first event, on_page_type_publish, is fired whenever a page type is published into a page on the site. This happens either through the composer panel, or the Check-In side panel. The next event, on_page_version_approve, is fired any time a new version of a page is approved. This is important to hook into because this new version could come with its own new URL slug. Finally, we hook into on_page_move in order to check whether a Blog Entry is being moved somewhere and, if it is, recalculate the paths at that time.