PrestaShop Subcategories to External Links: A Developer's Guide for PS 8.2+
As e-commerce migration experts at Migrate My Shop, we frequently encounter unique challenges that push the boundaries of standard PrestaShop functionality. One such scenario, recently highlighted in a PrestaShop forum thread, involves redirecting subcategories to external web pages. This isn't a common request, but it's a powerful feature for specific business models, such as affiliate programs, brand partnerships, or directing users to manufacturer-specific landing pages.
Let's dive into how to achieve this in PrestaShop 8.2 and beyond, ensuring your solution is robust, SEO-friendly, and maintainable.
The Challenge: Linking PrestaShop Subcategories to External URLs
The core problem, as articulated by MKZ Industries in the forum, is the desire to have a subcategory (e.g., 'Motorola' under 'Mobile phones') link directly to an external website (e.g., https://www.motorola.com) rather than an internal PrestaShop category page. This redirection should ideally open in a new tab and maintain good SEO practices.
Older PrestaShop versions might have pointed developers towards files like modules/blocktopmenu/blocktopmenu.php. However, with PrestaShop 8.2, this module has evolved into ps_mainmenu, and direct file modifications are generally discouraged due to upgrade complications.
Why Not Just Use .htaccess Redirects?
An initial thought for many developers is to use server-side .htaccess redirects. While effective for permanent URL changes, MKZ Industries rightly raised concerns about SEO. When a user hovers over a link, they expect to see the destination URL. An .htaccess redirect means the link in the HTML still points to an internal PrestaShop URL, and the redirection only happens after the click. Google and other search engines prefer direct, transparent linking, and users appreciate knowing where they're headed.
For external links, we want the actual external URL to be visible in the browser's status bar on hover, and the link to be a standard HTML tag.
Understanding PrestaShop's Menu & Category Rendering
The key to solving this lies in understanding how PrestaShop renders its navigation elements. The user's attempt to modify modules\ps_mainmenu\ps_mainmenu.php in the generateCategoriesmenu function was a step in the right direction:
foreach ($categories as $key => $category) {
$node = $this->makeNode([]);
if ($category['level_depth'] > 1) {
$cat = new Category($category['id_category']);
if ((int)$cat ->id_category == 12)
$link = "https://www.motorola.com";
else
$link = $cat->getLink();
// Check if customer is set and check access
if (Validate::isLoadedObject($this->context->customer) && !$cat->checkAccess($this->context->customer->id)) {
continue;
}
} else {
$link = $this->context->link->getPageLink('index');
}
}
This code successfully alters the link for category ID 12 within the main menu. The reason it only works for the main menu is that the ps_mainmenu module is specifically responsible for rendering the top navigation bar. The category tree often displayed in sidebars or other parts of the layout is typically handled by a different module, such as ps_categorytree (formerly blockcategories) or directly within the theme's templates.
Robust Solutions for External Category Links in PrestaShop 8.2+
To implement this functionality comprehensively and maintainably, we recommend a module-based approach or a well-structured theme override.
1. The Custom Module Approach (Recommended for Maintainability)
Creating a custom module is the most robust and upgrade-safe way to achieve this. It allows you to encapsulate your logic and configuration, making future PrestaShop upgrades or migrations smoother.
- Module Structure: Create a new module (e.g.,
mymodule_externalcategories). - Configuration: Provide a back-office interface within your module to map specific category IDs to external URLs. This avoids hardcoding IDs like
12in your code. - Hooking into Display:
- For Main Menu: Your module can hook into
displayTopor override theps_mainmenumodule's template if necessary. However, the user's existing code snippet withinps_mainmenu.phpshows a direct modification. A better approach would be to override theps_mainmenumodule's template (e.g.,themes/yourtheme/modules/ps_mainmenu/views/templates/hook/ps_mainmenu.tpl) and add your logic there, or use a hook to modify the menu items before rendering. - For Category Tree (Sidebar/Footer): The category tree is often rendered by the
ps_categorytreemodule. You would need to override its template (e.g.,themes/yourtheme/modules/ps_categorytree/views/templates/hook/ps_categorytree.tplorcategory-tree-branch.tplif your theme uses it) to inject your custom link logic.
- For Main Menu: Your module can hook into
- Logic in Template Override: Within the overridden template, you'd iterate through categories. For each category, check if its ID is mapped to an external URL in your module's configuration. If it is, construct the
tag with the external URL andtarget="_blank". Otherwise, use PrestaShop's default{$category.url}or$link->getCategoryLink().
{if isset($external_links[$category.id_category])}
{$category.name}
{else}
{$category.name}
{/if}
Your custom module would pass the $external_links array to the template.
2. Theme Override (Less Ideal, but Simpler for Quick Fixes)
If you're comfortable with theme-level modifications and understand the implications for theme updates, you can directly modify your child theme's templates.
- Identify Relevant Templates: Look for templates responsible for rendering category links. Common ones include:
themes/yourtheme/templates/catalog/_partials/category-tree-branch.tplthemes/yourtheme/modules/ps_mainmenu/views/templates/hook/ps_mainmenu.tplthemes/yourtheme/modules/ps_categorytree/views/templates/hook/ps_categorytree.tpl
- Implement Logic: Similar to the module approach, you'd add conditional logic within these templates. However, hardcoding category IDs directly into the template is less flexible. A better approach would be to define an array of external links in your theme's
functions.phpor a custom Smarty plugin and then access it in the template.
SEO Best Practices for External Links
When linking externally, always consider SEO:
target="_blank": Opens the link in a new tab, improving user experience by keeping them on your site.rel="nofollow noopener"orrel="sponsored":nofollow: Tells search engines not to pass link equity (PageRank) to the linked page. Use this if you don't want to endorse the external site or if it's an affiliate link.noopener: A security measure to prevent the opened page from having control over your original page.sponsored: Use for links where you've received compensation (e.g., affiliate links, paid placements).
- Descriptive Anchor Text: Use relevant text for the link (e.g., "Visit Motorola's Official Site") instead of generic phrases.
Migrate My Shop's Perspective: Customizations and Migrations
At Migrate My Shop, we understand that custom functionalities like external category links are crucial for many businesses. When planning a PrestaShop migration or upgrade, these customizations need careful attention.
- Review and Refactor: Direct core file modifications (like the original
blocktopmenu.phpidea) are migration nightmares. Even direct modifications tops_mainmenu.phpare problematic. A well-structured custom module is significantly easier to review, refactor, and port to a new PrestaShop version. - Compatibility: We ensure that any custom code remains compatible with the target PrestaShop version, addressing deprecated functions or changed module structures.
- Performance: Custom code should be optimized to not negatively impact your shop's performance.
If you have complex customizations or are planning a PrestaShop migration, don't hesitate to reach out to our experts. We specialize in seamless transitions, ensuring all your unique functionalities are preserved and optimized.
Conclusion
While PrestaShop is primarily designed for internal navigation, linking subcategories to external websites is entirely achievable with the right approach. By understanding how PrestaShop renders its navigation and employing best practices like custom modules and template overrides, you can implement this functionality robustly and maintainably. Remember to always prioritize SEO and user experience, and for complex scenarios or migrations, consider leveraging the expertise of specialists like Migrate My Shop.