I have a module that loops through all_widgets looking for a specific type of module and retrieving data from it.
We currently use it on a blog template and it works well but we have added it to a different page and it doesn’t work.
On debugging I can see that on the new page if I check all_widgets|length it returns 5. But if I look in the developer info for the page, the array is nearly 200 long.
If I check all_widgets|length on a blog post where it works I correctly get 39.
I have spent ages debugging this and can’t get to the bottom of it. The only thing I can think is perhaps there is a limit to the maximum array size you can loop through? Could it be its breaking because the array is so big, but works fine on the shorter blog posts.
I’d say, there’s a limit for for-loops around 10k, but as it’s very unlikely that somebody would loop through such an amount, you can say there’s no limit
What is being stored in all_widgets and what are you trying to achieve?
Unless you add export_to_template_context to the module, modules, will be rendered. Furthermore, it’s not possible to grab the info from a module and use it a different one - unless you change the whole default setup. Grabiing the module info and use it in a template is possible (see export_to_template_context link)
Many thanks for coming back to me. That is interesting to know on the limit. It certainly doesn’t sound like that could be the cause then. Essentially I am looping through all modules on the page looking for “Blog Section Heading” modules and then using this to construct a Table of Contents dynamically for the article. Here is my code:
{% set headings = [] %}
{% set track = [] %}
{% for widget in all_widgets %}
{% if widget.custom_widget_display_name == "Blog Section Heading" && widget.params.title %}
{% set level = widget.params.heading_type ? widget.params.heading_type|replace('h', '')|int : 2 %}
{% set anchor = widget.params.anchor ? widget.params.anchor : slugify.output(widget.params.title) %}
{% do headings.append({
title: widget.params.title,
id: anchor,
anchor: widget.params.anchor,
slug: slugify.output(widget.params.title),
type: widget.params.heading_type,
level: level,
indent: level > track|last,
outdent: level < track|last
}) %}
{% do track.append(level) %}
{% endif %}
{% endfor %}
As I say, it works perfectly on the blog posts, but on a page, all_widgets is only looping 5 times, even though in the developer info for the page, I can see there are nearly 200 items in the array.
I am not using export_to_template_context as the modules themselves still do render.
Hi @NewMoon and thanks for sharing your code with us!
To access module data on a page without using export_to_template_context, a helpful way is to reference content.widgets like this:
{{ content.widgets.module_name.body.parameter }}
You might notice that all_widgets only loops a handful of times on pages, even if you see many items in developer info. This difference means it may work a bit differently for pages than for blog posts.
I recommend using content.widgets to access your modules’ data and create your table of contents, it’s a reliable approach!
Let me know if you have any questions!
Thanks and have a wonderful day!
Bérangère This post was created with the assistance of AI tools
@BérangèreL Thank you for your reply. I have done some testing but unfortunately even on the blog I only get 5 loops out of content.widgets. It is so strange!
Hey @NewMoon and thanks for getting back to us!
Just a couple of helpful reminders:
- content.widgets won’t access global modules.
- If you’d like to see how data is stored, feel free to use Developer Info for a closer look!
Now, let’s consult our Top Experts: Hi @Anton, @Mike_Eastwood and @zach_threadint do you have any insights to share with @NewMoon, please?
Thanks so much and have a lovely day!
Bérangère