Creating layouts and theme positions

I started a small experiment some time ago to replace all the frontend content on a website with L&L solutions, and over time it has evolved into something close to a full WP theme.

However, I am still using Elementor’s template system to control where L&L templates are displayed, E.g. Header, Footer, Single Page, Category etc. This works fine, but it’s not something I want Elementor to handle forever.

It seems the best way to solve this is to use layouts and theme positions, but I only get the ‘Content’ position. How can I add more theme positions? I assume these are just hooks that can be added with PHP or something. Thanks.

1 Like

For now I think we’ve only built out support for the Kadence theme header and footer locations since that’s generally what we’re using internally. We’ll have to think about how to allow themes to declare support. I’d definitely like to see us add support for more generic “parts” as well. Ideally something Beaver Themer-style that would also empower users to add support in their functions.php file: Add Themer support to your theme | Beaver Builder Knowledge Base

2 Likes

I can’t find instructions for how to use it, but I did look through the repo and found a “register_theme_positions” function that seems to be inspired from the BB functionality I just linked to. I’ll ask around to see if I can get some documentation/find out whether it would allow to register your own theme positions.

1 Like

Thanks, my theme is simple and would only need three positions - Header, Footer and Content.

1 Like

Alright, so I got a reply:

The syntax to add support is the following:

$template_system = tangible_template_system();

$template_system->register_theme_positions([
  [
    'name'  => 'custom_hook_name',
    'label' => 'Custom part',
  ], [
    'name'  => 'another_custom_hook_name',
    'label' => 'Another custom part',
  ]
]);

image (3)

You can also register positions inside sections, purely for aesthetics and keeping things organized:

How to add sections
$template_system->register_theme_position_groups([

  'custom-section'  => [
    'label' => 'Custom section',
    'hooks' => [
      [
        'name'  => 'custom_hook_name',
        'label' => 'Custom part',
      ], [
        'name'  => 'another_custom_hook_name',
        'label' => 'Another custom part',
      ]
    ]
  ]

]);

image (4)

The useful part

So in theory, you could add this to your functions.php file:

if( ! function_exists('tangible_template_system') ) return;

$template_system = tangible_template_system();

/**
 * Adds support for L&L layouts
 * 
 * If we add it in a theme it's OK because it will only be loaded when the theme
 * is activated
 * 
 * However, if it's from a plugin we need to make sure the related theme is activated
 * before calling register_theme_position_groups()
 */

$template_system->register_theme_position_groups([

    'header'  => [
      'label' => 'Header',
      'hooks' => [
        [
            'name'  => 'my_header_hook',
            'label' => __( 'Header', 'my_text_domain' ),
        ],
        [
            'name'  => 'my_before_header_hook',
            'label' => __( 'Before Header', 'my_text_domain' ),
        ],
        [
            'name'  => 'my_after_header_hook',
            'label' => __( 'After Header', 'my_text_domain' ),
        ],
      ],
    ],

    'content' => [
      'label' => 'Content',
      'hooks' => [
        [
            'name'  => 'my_before_content_hook',
            'label' => __( 'Before Content', 'my_text_domain' ),
        ],
        [
            'name'  => 'my_after_content_hook',
            'label' => __( 'After Content', 'my_text_domain' ),
        ],
      ],
    ],

    'footer' => [
      'label' => 'Footer',
      'hooks' => [
        [
            'name'  => 'my_footer_hook',
            'label' => __( 'Footer', 'my_text_domain' ),
        ],
        [
            'name'  => 'my_before_footer_hook',
            'label' => __( 'Before Footer', 'my_text_domain' ),
        ],
        [
            'name'  => 'my_after_footer_hook',
            'label' => __( 'After Footer', 'my_text_domain' ),
        ],
      ],
    ],

  ]);

The dev also provided me with a barebones custom theme as an example but I don’t seem to be able to upload zips here (which seems prudent) so let me know if you want that and I can find a way to publish it elsewhere or send it to you :slight_smile:

I haven’t had a chance to test this on my end, so do let me know how it goes!

2 Likes

Thanks for all the info!

I will have to enlist the help of a developer friend to implement this properly but the demo site would be useful.

Phil got back to me letting me know he was able to get this working in the Underscores starter theme! Sounds like this approach should work :slight_smile:

3 Likes

Yes, this works well and allowed me to completely remove Elementor from my solution, which is a big win. :slight_smile:

I got it working with both Bootscore and Underscores while testing.

If you want to create a WP theme using Tangible layouts, I would recommend Underscore, as this is a good barebones starter theme that is easy to work with.

Bootscore is good too, but it comes with lots more features and code which you may not need.

If this functionality was added to the docs with the demo site zip, I’m sure some people would find it very useful.

1 Like

I’m sorry to revive an old thread, but I’m facing this same issue trying to implement theme locations. If it would be best to start a new thread, let me know.

I have added The useful part code above, but I’m not sure what to do with the hooks my_header_hook and so on. Do I need to create a function() and add_action() in functions.php, and then call them in the header template? I’ve experimented with that, but it’s not really working as expected. The positions are showing up in the layout Theme position dropdown, but I’m unclear on how to link that to a location in my template.

@julia I know it’s been many months, but if you happen to still have the zipped barebones theme, I would love to have it as a reference.

I managed to partially answer my own question. I’ve added the following, and this at least loads the layout when it’s assigned:

functions.php:

function display_my_header_hook() {}
add_action( 'my_header_hook', 'display_my_header_hook', 5 );

header.php:

<?php do_action( 'my_header_hook' ); // Add Loops & Logic Header layout ?>

However, I’m still struggling with how to make this conditional, only loading if a layout has been assigned to the position.

Hi @Beardmancer, you can download it here. It should help you understand how this all works. :slightly_smiling_face:

1 Like

@Rips This is perfect, thank you very much for sharing! I really appreciate it.

2 Likes