Theme header/footer are global - has anyone hacked their way around to have custom header/footers per template?
Reproduction steps
Create a new template within a theme. Make a change to the header/footer. It’s global.
Additional info
I realise this is default behavior, but looking to circumvent/hack around it. I’m also open to alternatives (besides the obvious of multiple stores and/or the extremely expensive “Shopify Plus”.
Sorry - that went right over my head… could you give more information?
For my situation, I’d want something like
If template = X then “menu X”
If template = Y then “menu Y”.
The menu value seems to be set in a .json file, and I’m not sure if I can recover the template name from somewhere. Or indeed, exactly where to do this…
Metaobjects
Could also be using metaobjects having entries that contains a menu reference object and a text field where you can type the related template.
Then with liquid you can access all metaobjects of that type and find the entry where the template text field matches current template. Render that menu
Blocks
Just like the metaobjects solution you could do the same with blocks in the header section. Create a block that contains those two values, and then find the relevant block wtih liquid based off the current template.
Just a few possibilities on top of my head. But it really depends on the exact use case.
According to your need, the metaobject would be your best bet:
Create a header_menu metaobject definition
a. template_handle text field to link the template
b. link_list_handle text field to link the menu
Create header_menuentries accordingly
Inside your sections/header.liquid file, add the default_header_menu metaobject setting to gracefully fallback
Add the following code
Warning: The implementation will be tightly linked to the section established architecture, take it with a grain of salt
{% liquid
assign header_menu_list = metaobjects.header_menu.values
assign header_menu = section.settings.default_header_menu
for menu in header_menu_list
assign associated_template = menu.template_handle.value
if associated_template == template
assign header_menu = menu
break
endif
endfor
assign menu_handle = header_menu.link_list_handle.value
assign link_list = linklists[menu_handle]
for link in link_list.links
# Here, you have the reference to every link
endfor
%}
Configure the default_header_menu setting in the JSON / theme customizer
Enjoy !
There are many ways to tackle this, but this should be the more scalable approach !
Thanks for this. It looks really cool. After setting it up, I get template coming out, but it never matches associated_template (either AT isn’t getting assigned properly or it’s not matching for “technical reasons”. I did see that template comes out as “pages.templatename”, so I updated the template_handle values to add “pages.”, but still no luck.
I also (due to lack of knowledge) didn’t seem to be able to pull out the value of associated_template as it runs through the loop.
After the loop, header_menu.link_list_handle.value is ““ and link_list gives “EmptyDrop”, but this makes sense if template and associated_template never match (I’ve taken out the graceful fallback for testing purposes).
Any debugging ideas greatly appreciated.
On further digging, I rewrote your code (shonkily, I’m sure there’s a better way), so that I could see what’s happening in the for menu in header_menu_list loop. It correctly runs 4 times for the four metaobjects values I have. so the first assign of the metaobjects.header_menu works. But it doesn’t seem to be able to read template_handle.value, or assign it to associated_template, this is always blank. I tried hard-coding the link_list, and this works, so i’ts just this bit.
I eventually recreated the metaobject, and it was not working because template_handle was assigned as the “display name”, creating a separate display name didn’t fix it. I had to delete the metaobject and recreate it with a separate display name at creation time. And then one little typo (from the endless changes I had made), and it works!
So - key Gotchya is don’t let Shopify make one of the fields you want to use a “Display Name”, or it won’t work!
Thankyou very much, both of you! I can now use this to hack away at all sorts of stuff!
I updated my code after checking it and found a mistake (updated my earlier message):
{% liquid
# This works
assign menu_handle = menu_header.link_list_handle.value
assign link_list = linklists[menu_handle]
# This does not work
assign link_list = linklists[menu_header.link_list_handle.value]
%}
I guess it has to do with some obscure order of operations, but that’s what you get for not checking before posting ! I checked with different templates and it works on my end, hope it helps !
Weird. Your original version actually worked for me (after the fixups I mentioned). But as you said - weird order of operations internally. Thanks again for your help - greatly appreciated!