Skip to main content
Topic: Question about theme layers  (Read 5250 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Question about theme layers

Is it possible to make visible to the theme in what order the different theme layers are called? Beyond html/body its a bit bewildering what gets called next..for example in Display template: its visible - sort of - what comes next by looking at the actual output in the page, but it would be nice to know exactly what comes next.

The problem for me is that I want to collect several smaller subtemplates into a overall markup tag for special layout purposes. Right now it is a bit hit and miss without knowing this structure(and indeed if any mods add to it later on). 

I see $context has some stuff listed..but it does not appear to list the subtemplates in the correct order... 

Re: Question about theme layers

Reply #1

Quote from: Bloc – Is it possible to make visible to the theme in what order the different theme layers are called? Beyond html/body its a bit bewildering what gets called next..for example in Display template: its visible - sort of - what comes next by looking at the actual output in the page, but it would be nice to know exactly what comes next.

The problem for me is that I want to collect several smaller subtemplates into a overall markup tag for special layout purposes. Right now it is a bit hit and miss without knowing this structure(and indeed if any mods add to it later on). 

I see $context has some stuff listed..but it does not appear to list the subtemplates in the correct order... 

Look at the Template Layers class and the output of getLayers. I think that contains what you are looking for.

Also here; https://github.com/elkarte/Elkarte/blob/f358500749637aeff933dfffc00e0b71139c3ed2/sources/subs/TemplateLayers.class.php#L119
Last Edit: February 07, 2021, 07:57:54 pm by tino

Re: Question about theme layers

Reply #2

This https://github.com/elkarte/Elkarte/wiki/Template-layers may also help .. but please note that has not been updated that for 1.1, you know how documentation goes,  so there will be some inconsistencies.   Perhaps @emanuele will provide a few more details as well.

Re: Question about theme layers

Reply #3

Great! :) I see the class can list the layers in the public getLayers() function. Only have to find out what the variable which use this class is called..and if its possible to reach it from the theme.

Re: Question about theme layers

Reply #4

Ok, still confused..as I see $context gets all the info I need (I think) but again, the ordering is strange:
Code: [Select]
           [layers:protected] => Template_Layers Object
                (
                    [_error_safe_layers:Template_Layers:private] => Array
                        (
                            [0] => html
                            [1] => body
                        )

                    [_is_error:Template_Layers:private] =>
                    [_all_general:protected] => Array
                        (
                            [quickreply] => 0
                            [pages_and_buttons] => 100
                        )

                    [_all_after:protected] => Array
                        (
                        )

                    [_all_before:protected] => Array
                        (
                        )

                    [_all_end:protected] => Array
                        (
                            [messages_informations] => 10000
                        )

                    [_all_begin:protected] => Array
                        (
                            [html] => -10000
                            [body] => -9900
                        )

                    [_general_highest_priority:protected] => 200
                    [_end_highest_priority:protected] => 10100
                    [_begin_highest_priority:protected] => -9800
                    [_sorted_entities:protected] => Array
                        (
                            [0] => html
                            [1] => body
                            [2] => quickreply
                            [3] => pages_and_buttons
                            [4] => messages_informations
                        )

                )

Here quick-reply is listed BEFORE pages_buttons and messages_information, which all correspond to the subtemplates named the same..but its not how its presented on the page(only markup, no css shown). So how does the script go from that to whats showing?

Re: Question about theme layers

Reply #5

That’s handled in the Theme file.

https://github.com/elkarte/Elkarte/blob/98b5d91e6d9e004324e91ac2268eecc4befec54f/themes/default/Theme.php

Although I think that Elkarte is moving away from the $context global variable. So it might not be that useful to rely on that going forward.

What is it you’re trying to do?

Re: Question about theme layers

Reply #6

Really simple really..I want to add the numerous subtemplates like pages/quickreply/modbuttons etc. into a dedicated sidebar. So I need to know where to put the start of the container tag - and the end tag. Right now I am not sure where things begin and end...

I can already do this with just CSS - that is, put all those in a grid so it goes on the right. The trouble begins once I want to target all those as one item, for example to make it stop scrolling once they reach the top ..or just make it a sidebar that can fly out when called(mainly for phones). Currently i can't do this just with minor changes in markup + CSS.

Re: Question about theme layers

Reply #7

You can reorder the items sorted entities by changing their priority.

Then insert your template to add the required start container tag and then another template to add your end container tag.
That's probably the best way to implement it.

If you know what the templates are called anyway.

 

Re: Question about theme layers

Reply #8

Ok, thanks. For now I think I just leave it be, pending a deeper look into how the theme system works.  :D

Re: Question about theme layers

Reply #9

@Bloc the layers are sorted only just before being used.
You can forcefully sort them with:
Code: [Select]
$layers = Template_Layers::getInstance()->prepareContext();
Though you may want to do it as late as possible before the output, just to avoid missing something.

That said, probably you don't even need to sort them, I mean, you could just hook up somewhere before template_header being called (I guess call_integration_buffer is as good as any other), get all the layers defined up until that moment, filter those you want to move somewhere else, remove them, add your sidebar and render the layers in the sidebar.
Something like:
Code: [Select]
global $existing_layers;
$interested_in_layers = ['quickreply', 'pages', 'moderation', 'etc.'];
$existing_layers = [];
$layer_obj = Template_Layers::getInstance();
foreach ($layer_obj->getLayers() as $layer)
{
    if (in_array($layer, $interested_in_layers))
    {
        $existing_layers[] = $layer;
        $layer_obj->remove($layer);
    }
}
$layer_obj->addBegin('my_sidebar');


function my_sidebar_above()
{
  global $existing_layers;
  echo '<your sidebar markup>';

  // Sort to whatever order you want them to be
  foreach ($existing_layers as $layer)
  {
    loadSubTemplate($layer . '_above', 'ignore');
  }
  // Reverse the sorting
  foreach ($existing_layers as $layer)
  {
    loadSubTemplate($layer . '_below', 'ignore');
  }

  echo '</your sidebar markup>';
}

I can't guarantee it works (even more because I just wrote it here without any kind of validation nor testing, so...), but that should be the general idea.
Bugs creator.
Features destroyer.
Template killer.

Re: Question about theme layers

Reply #10

Thanks , I will test this out. :)

I am trying to 1) avoid rewriting the whole template and 2) avoiding having to target all those subtemplates with CSS..which I already do, but some things are just not possible without collecting them somehow.

One other aspect is that I might be able to do this with other templates too, anywhere where stuff should go in that custom sidebar, without rewriting them too. At least for this theme anyway. 

I have to note one small issue in script.js: the "jump_to" code there have a single &nbsp; inserted. I could not figure where it was coming from since the inline js seems to disregard me removing it from there. It would seem it just took it from script.js regardless..so I had to copy over the entire script.js to my theme just to change it(..). Why is it there? Well, I guess to add some natural distance to the submit button..but it really hinders anyone wanting to control that distance by CSS. Particulary if you want a vertical placement of the input/select/submit and don't want that distance there. It also affects using display: grid and grid-template-areas , as its regarded as a single item by the grid ..but possible to style since its not a markup tag(...)

But, as said, a small issue. :) I might just leave it out anyway, depends if I find other stuff in script.js that I need to change. 

Re: Question about theme layers

Reply #11

That's worth a bug report. ;)
Master of Expletives: Now with improved family f@&king friendliness! :D

Sources code: making easy front end changes difficult since 1873. :P

Re: Question about theme layers

Reply #12

I checked and there are a total of (9) &nbsp in the JS files in of course (9) different files.

I have to be honest, injecting an occasional &nbsp is one of my favorite tricks to fix things  O:-)

I'll log this to fix (remove) what we can in 2.0, thanks for reporting.

Re: Question about theme layers

Reply #13

Great :)  You can of course use those still..but it would be better to use spans around them - or better yet, JUST use a span with a "breaking space" dedicated class. :D

Re: Question about theme layers

Reply #14

New question..is there a way to add a hook only to be executed when a theme is run? That is, not permanently added.

I'd like to try adding the sidebar code but am a bit lost as to how the theme would be able to integrate with hooks. I don't want to make a mod for this either.

I've seen from the source code that adding Theme.php inside the custom theme apparantly makes Elkarte use that..and that seems to be interesting as a way to customize the theme engine(possibly), but it still calls the Templatelayers.class which seems not be fecthed from anywhere else that Sources anyway.

I am kind of deterred by the fact the subtemplates is not so easily managed by the theme in Elkarte. I mean, I see the reasons for it, but it does limit what a theme could do. You are kind of stuck with the order they are presented in. But I acknowledge that there is probably not a high demand for it ...other than for myself :) ..so I guess its a non-priority. I'll keep tugging at it until I find a work-around because I think Elkarte is by far the better of all forked SMF scripts, including SMF(2.1) itself.