Inside Prestashop – SEO Friendly URLs (2/2)

Prestashop Friendly URL’s, how it works (part 2)

In the previous article, I explained how the friendly URL are decoded by the dispatcher class. But this was only half the way to understand how the friend URL mechanism is implemented in Prestashop (what I call « Prestashop PHP core code »). In this article, we will have a look at how these friendly are built. Fasten your seat belts, we will travel inside the Prestashop maze!

Building category URL in ps_treeview module

When I created the custom code for the FadeurParts.be project, I needed a front-office category navigation module working with my filter. So, I made a copy of the native module of Prestashop, the well known « Category Tree View » (modules/ps_treeview) which is displayed, by default, on the left side of the front-end (hooked to displayLeftColumn position). I needed this because, when the customer is filtering products by tractor, I wanted to show only the categories containing products for the selected tractor. So I incorporated this navigation within one of my modules. If you want to know more about this custom development, start by reading this article: FadeurParts.be Technical (1) – Overview of the project.

Therefore, the « tractor filter » won’t work if you use another way to navigate the categories, such as the menu or an other navigation module provided with a theme.

Why I’m writing this ? Because I’ve not investigated how the category URLS are built within other modules. Therefore, the following explanation apply only to my custom category navigation module and to the native Prestashop ps_treeview. Now, I guess that other modules work the same way…

How is the category URL built ?

If you have a native PS 1.7 setup, you can have a look at module/ps_treeview.php. This class takes care of building the category tree view that you see on the left panel of the Prestashop front-end.

  • The method ps_treeview->getTree() calls the method Link->getCategoryLink() which prepares the URL.
  • The final formatting, depending wether the friendly URL are on or off, is delegated to Dispatcher->createURL().

In the next section, I will describe how it is done for the product URL, which is similar.

Building product URL

I’m wondering wether the process of building product URL is overly complex in Prestashop. In my humble opinion, this reflects some architectural weaknesses that Prestashop has in the field of OO (object oriented) programming and MVC (model-view-controller) architecture, probably due to legacy. But I’m leaving this discussion up to the design gurus (also called application architects)…

Controller class inheritance class diagram

But before we jump to the sequence diagram, let’s have a look at the class diagram showing a static view of the class structure. It shows the classes inheriting from the class Controller and the relationship with class Product and Category. It’s important to have that structure in mind because you’ll often see PHP statements in which a class calls its own methods, in the form:

$this->class_method();

The method may not defined in the class itself, but resides in one of its ancestors. You should get familiar with general principles of inheritance in OO programming and how these principles are implemented in PHP (extends, implements, abstract…) before going any further.

Prestashop Controller class inheritance class diagram (UML)

Product search sequence diagram

Nothing is worth a UML sequence diagram to show classes and methods in action! This one, below, shows how  CategoryController, controls the Prestashop front-end when viewing the category page. This page:

Prestashop category page (CategoryController in action)

Note: the CategoryController takes care of retrieving the products that are displayed on the page. There is also a ProductController. This one takes care of displaying the products when the product page is displayed.

When the user clicks a link on the front-end, here is what happens:

  • index.php (in your site root directory) creates an instance of Dispatcher and calls Dispatcher->Dispatch().
  • The dispatcher analyses the received URL and yields execution control to the controller specified in the URL, CategoryController in this case. When friendy URL is off, this is straightforward because the URL contains a parameter controller=category. When friendly URL is on, it’s a bit more complex, as I explained in the first part of this article.
  • CategoryController will retrieve the data from the database, prepare them for display and pass them to Smarty.

A quick explanation on how to read a UML sequence diagram.


How the URL is created:

  • Class ProductAssembler calls Product->getProductProperties for each product retrieved from the database (all products belonging to the current category, remember, we’re under the control of CategoryController).
  • Link->getProductLink() is called to actually build the URL of the product by gathering the components.
  • The final formatting of the URL is delegated to the Dispatcher->createURL() because this one knows how to build a friendly URL.

Now, we could discuss wether the responsibilities are logically delegated. One could argue that the class link shouldn’t be aware of category or product and might be a better choice for taking care of createURL(). But this is not the object of this article.

Conclusion

The loop is closed. We understand how the URL is build when Prestashop prepares the page to be displayed and we understand how the URL is decoded when it’s received by the dispatcher.

It’s interesting to note, though, that the first thing that Prestashop does is to transform friendly URL back to a regular URL by assigning values to the $_GET array by the controller (see Dispatcher->getController()):

$_GET['controller'] = $this->controller;

foreach ($route['params'] as $k => $v) {
    $_GET[$k] = $v;
}