Skip to content

Global refactor of themes section#2129

Open
tblivet wants to merge 4 commits intoPrestaShop:9.xfrom
tblivet:feat/themes-refactor
Open

Global refactor of themes section#2129
tblivet wants to merge 4 commits intoPrestaShop:9.xfrom
tblivet:feat/themes-refactor

Conversation

@tblivet
Copy link
Copy Markdown
Contributor

@tblivet tblivet commented Apr 1, 2026

Questions Answers
Branch? 9.x
Description? Full refactor of the themes/ documentation section, Hummingbird-first, restructured into 7 sections. This PR contains major changes and should be reviewed with a local build of the docs.

Note: a separate PR has been submitted to exclude CLAUDE.md files from the Hugo build: PrestaShop/devdocs-site#44

Sorry for the size of this PR, the nature of a full section refactor made it impossible to split into smaller atomic pieces without losing coherence.
Fixed ticket? --
Sponsor company @PrestaShopCorp

Copy link
Copy Markdown
Contributor

@ga-devfront ga-devfront left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial feedback: I haven't finished the review yet, but this is to be able to start working on the responses/feedback.

[getting-started-guide]: https://docs.prestashop-project.org/v.8-documentation/v/english/getting-started
[system-requirements]: {{< relref "/9/basics/installation/system-requirements" >}}
[clone-the-repository]: {{< relref "/9/themes/getting-started/setting-up-your-local-environment" >}}
[clone-the-repository]: {{< relref "/9/themes/getting-started/environment-setup" >}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to remove this link, this is a non sens

Comment on lines +18 to 20
{{% notice warning %}}
The **Classic theme is deprecated** for new development starting from PrestaShop 9.1. It remains available for backward compatibility but will not receive new features. For Classic-specific documentation, refer to the [v8 theme docs]({{< relref "/8/themes" >}}).
{{% /notice %}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to send it to top (after the title) it's the main information of the page.


| Tool | Status | Purpose |
|------|--------|---------|
| **Node.js 20.x + npm 8+** | Recommended | Asset compilation, dev workflow, linting |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| **Node.js 20.x + npm 8+** | Recommended | Asset compilation, dev workflow, linting |
| **Node.js 20.x + npm 8+** | Recommended | Dependency management, asset compilation, task running, and linting |


### Node.js

Install from [nodejs.org](https://nodejs.org/). To manage multiple Node.js versions, use [nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Install from [nodejs.org](https://nodejs.org/). To manage multiple Node.js versions, use [nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm).
Install from [nodejs.org](https://nodejs.org/). To manage multiple Node.js versions, use [nvm](https://github.com/nvm-sh/nvm), [fnm](https://github.com/Schniz/fnm) or [mise](https://github.com/jdx/mise).


{{% notice info %}}
Hummingbird requires **PrestaShop 9.1 or later**.
{{% /notice %}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{{% /notice %}}
{{% notice info %}}
Hummingbird's compatibility is strictly tied to specific PrestaShop releases. To find the correct theme version for your store, please refer to the compatibility matrix on the [Hummingbird repository].
{{% /notice %}}

I think it would be better to get a compatibility matrix on HB readme because for moment PrestaShop doesn't manage well themes upgrade and compatibility.

Comment on lines +118 to +129
1. `en-US/catalog/product-3.tpl` — locale + entity ID
2. `catalog/product-3.tpl` — entity ID only
3. `en-US/catalog/product.tpl` — locale only
4. `catalog/product.tpl` — default

<div class="mermaid">
graph TD;
A(en-US/catalog/product-3.tpl)
A-->B(catalog/product-3.tpl);
B-->C(en-US/catalog/product.tpl);
C-->D(catalog/product.tpl);
</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to place them side by side (the image on the left perhaps) in order to save space that is not used on a normal screen.

Comment on lines +135 to +150
1. `en-US/catalog/listing/category-9.tpl`
2. `catalog/listing/category-9.tpl`
3. `en-US/catalog/listing/category.tpl`
4. `catalog/listing/category.tpl`
5. `en-US/catalog/listing/product-list.tpl`
6. `catalog/listing/product-list.tpl` — final fallback

<div class="mermaid">
graph TD;
A(en-US/catalog/listing/category-9.tpl)
A-->B(catalog/listing/category-9.tpl);
B-->C(en-US/catalog/listing/category.tpl);
C-->D(catalog/listing/category.tpl);
D-->E(en-US/catalog/listing/product-list.tpl);
E-->F(catalog/listing/product-list.tpl);
</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same


This fallback chain applies to all listing pages (new products, best sellers, search results, etc.) — they all ultimately fall back to `product-list.tpl`.

See [Listing pages]({{< relref "/9/themes/concepts/templates/listing-pages" >}}) for how listing templates work, including AJAX updates.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be interesting to put it in a note so that it's more visible, what do you think?


Template inheritance allows you to extend a parent template and only redefine the blocks you need. A parent template defines named `{block}` regions; a child template extends it with `{extends}` and overrides only the blocks it wants to change. Everything else is inherited as-is.

The illustration below shows an illustrative example: `page.tpl` defines the global page structure, `product.tpl` extends it with product-specific content, and `product-pack.tpl` extends the product page to only override the description part — everything else is inherited.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The illustration below shows an illustrative example: `page.tpl` defines the global page structure, `product.tpl` extends it with product-specific content, and `product-pack.tpl` extends the product page to only override the description part everything else is inherited.
The illustration below shows an illustrative example: `page.tpl` defines the global page structure, `product.tpl` extends it with product-specific content, and `product-pack.tpl` extends the product page to only override the description part, everything else is inherited.

We understand that it's a legacy system, but are we talking about a block or an extension here? I think we're a bit too confused.


| Strategy | Syntax | Behavior |
|----------|--------|----------|
| **Replace** | `{block name='foo'}...{/block}` | Completely replaces the parent block content |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add it's the default one if you define nothing insid {block}

Copy link
Copy Markdown
Contributor

@ga-devfront ga-devfront left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second part of my review, it's not finished yet.


This page covers how PrestaShop handles product listing pages and how the product list updates dynamically via AJAX.

Any page that displays a list of products — category, search results, new products, best sellers, etc. — uses the same listing system. They all share the same base template (`catalog/listing/product-list.tpl`) and receive the same `$listing` variable from their controller. Specific pages extend the base template and override only what differs.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Any page that displays a list of productscategory, search results, new products, best sellers, etc. uses the same listing system. They all share the same base template (`catalog/listing/product-list.tpl`) and receive the same `$listing` variable from their controller. Specific pages extend the base template and override only what differs.
Any page that displays a list of products, category, search results, new products, best sellers, etc. uses the same listing system. They all share the same base template (`catalog/listing/product-list.tpl`) and receive the same `$listing` variable from their controller. Specific pages extend the base template and override only what differs.


Any page that displays a list of products — category, search results, new products, best sellers, etc. — uses the same listing system. They all share the same base template (`catalog/listing/product-list.tpl`) and receive the same `$listing` variable from their controller. Specific pages extend the base template and override only what differs.

See [Template inheritance]({{< relref "/9/themes/concepts/templates/template-inheritance" >}}) for a real-world example.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See [Template inheritance]({{< relref "/9/themes/concepts/templates/template-inheritance" >}}) for a real-world example.
See [Template inheritance]({{< relref "/9/themes/concepts/templates/template-inheritance/#real-world-example-product-listing-pages" >}}) for a real-world example.

we can point directly on the real world example anchor.


When customers change sort order or paginate, PrestaShop updates the product list **without a full page reload**. Filter modules (like `ps_facetedsearch`) also use this same system to refresh results dynamically.

A key design decision: PrestaShop renders the updated HTML **server-side** and sends it back to the theme. The theme's JavaScript only needs to replace DOM placeholders — it does not need to parse JSON and reconstruct markup. This ensures no presentation logic is duplicated between Smarty and JavaScript.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A key design decision: PrestaShop renders the updated HTML **server-side** and sends it back to the theme. The theme's JavaScript only needs to replace DOM placeholders it does not need to parse JSON and reconstruct markup. This ensures no presentation logic is duplicated between Smarty and JavaScript.
A key design decision: PrestaShop renders the updated HTML **server-side** and sends it back to the theme. The theme's JavaScript only needs to replace DOM placeholders, it does not need to parse JSON and reconstruct markup. This ensures no presentation logic is duplicated between Smarty and JavaScript.

Comment on lines +70 to +77

| `data` property | Contains |
|-----------------|----------|
| `rendered_products_top` | Sort bar and result count HTML |
| `rendered_products` | Product grid/list HTML |
| `rendered_products_bottom` | Pagination HTML |
| `rendered_facets` | Filter sidebar HTML (when a filter module is active) |
| `rendered_active_filters` | Active filter tags HTML (when a filter module is active) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `data` property | Contains |
|-----------------|----------|
| `rendered_products_top` | Sort bar and result count HTML |
| `rendered_products` | Product grid/list HTML |
| `rendered_products_bottom` | Pagination HTML |
| `rendered_facets` | Filter sidebar HTML (when a filter module is active) |
| `rendered_active_filters` | Active filter tags HTML (when a filter module is active) |
#### `data` properties
| key | Contains |
|-----------------|----------|
| `rendered_products_top` | Sort bar and result count HTML |
| `rendered_products` | Product grid/list HTML |
| `rendered_products_bottom` | Pagination HTML |
| `rendered_facets` | Filter sidebar HTML (when a filter module is active) |
| `rendered_active_filters` | Active filter tags HTML (when a filter module is active) |

Comment on lines +16 to +17
- `_partials/stylesheets.tpl` — loops over registered stylesheets
- `_partials/javascript.tpl` — loops over registered scripts, supports async loading
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `_partials/stylesheets.tpl` loops over registered stylesheets
- `_partials/javascript.tpl` loops over registered scripts, supports async loading
- `_partials/stylesheets.tpl`: loops over registered stylesheets
- `_partials/javascript.tpl`: loops over registered scripts, supports async loading

2. Delete `assets/css/theme_rtl.css`.
3. Regenerate from the Back Office.

PrestaShop will generate a fresh `theme_rtl.css` from `theme.css`, then append the contents of `theme.rtlfix` at the end — your fixes are preserved across regenerations.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PrestaShop will generate a fresh `theme_rtl.css` from `theme.css`, then append the contents of `theme.rtlfix` at the end — your fixes are preserved across regenerations.
PrestaShop will generate a fresh `theme_rtl.css` from `theme.css`, then append the contents of `theme.rtlfix` at the end. Your fixes are preserved across regenerations.

Comment on lines +61 to +63
{{% notice tip %}}
Use CSS logical properties (`margin-inline-start`, `padding-inline-end`, `inset-inline-start`, etc.) instead of physical ones (`margin-left`, `padding-right`, `left`). Logical properties automatically adapt to text direction, reducing the need for RTL-specific overrides.
{{% /notice %}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is strange because we have an H2 heading for a notice.

Want to test it? Want to contribute to the project and share the feedback with the team? See [Hummingbird Github repository](https://github.com/PrestaShop/hummingbird).
| Page | Description |
|------|-------------|
| [CSS Architecture]({{< relref "/9/themes/hummingbird/css-architecture" >}}) | [Bootstrap 5.3](https://getbootstrap.com/docs/5.3/getting-started/introduction/), [BEM](https://getbem.com/naming/), SCSS, `@layer`, dark mode via color modes |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [CSS Architecture]({{< relref "/9/themes/hummingbird/css-architecture" >}}) | [Bootstrap 5.3](https://getbootstrap.com/docs/5.3/getting-started/introduction/), [BEM](https://getbem.com/naming/), SCSS, `@layer`, dark mode via color modes |
| [CSS conventions]({{< relref "/9/themes/hummingbird/css-architecture" >}}) | [Bootstrap 5.3](https://getbootstrap.com/docs/5.3/getting-started/introduction/), [BEM](https://getbem.com/naming/), SCSS, `@layer`, dark mode via color modes |

This page doesn't just talk about architecture, but mainly about conventions and best practices. I think we can rename the page too.

| Page | Description |
|------|-------------|
| [CSS Architecture]({{< relref "/9/themes/hummingbird/css-architecture" >}}) | [Bootstrap 5.3](https://getbootstrap.com/docs/5.3/getting-started/introduction/), [BEM](https://getbem.com/naming/), SCSS, `@layer`, dark mode via color modes |
| [JavaScript]({{< relref "/9/themes/hummingbird/javascript" >}}) | jQuery-free theme code, semantic `data-ps-*` attributes, event system |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [JavaScript]({{< relref "/9/themes/hummingbird/javascript" >}}) | jQuery-free theme code, semantic `data-ps-*` attributes, event system |
| [JavaScript conventions]({{< relref "/9/themes/hummingbird/javascript" >}}) | jQuery-free theme code, semantic `data-ps-*` attributes, event system |

We need to be consistant about this part (same as menu naming)

| [CSS Architecture]({{< relref "/9/themes/hummingbird/css-architecture" >}}) | [Bootstrap 5.3](https://getbootstrap.com/docs/5.3/getting-started/introduction/), [BEM](https://getbem.com/naming/), SCSS, `@layer`, dark mode via color modes |
| [JavaScript]({{< relref "/9/themes/hummingbird/javascript" >}}) | jQuery-free theme code, semantic `data-ps-*` attributes, event system |
| [Accessibility]({{< relref "/9/themes/hummingbird/accessibility" >}}) | EAA compliance, ARIA, keyboard navigation |
| [Development Workflow]({{< relref "/9/themes/hummingbird/development-workflow" >}}) | README link, troubleshooting, dev environment tips |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [Development Workflow]({{< relref "/9/themes/hummingbird/development-workflow" >}}) | README link, troubleshooting, dev environment tips |
| [Development Workflow]({{< relref "/9/themes/hummingbird/development-workflow" >}}) | Troubleshooting, dev environment tips |

I think we can remove README link about this part, it not add anymore to the description.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants