Sections

Sections or in other words blocks are pieces of “content” or “micro modules” that has separate model for data handling and template for view.

That allows to create standalone sections, with separated model and view layer, caching their model and view layer to prevent unnecessary execution of code when not needed. Thanks to this selective caching you can control what to cache on your website compared to other caching solutions where you have ability to do full page caching only.

If you worked with magento you know what I am am talking about. This way of coding is little slower than just creating a template file and including using get template part, but in other hand has better portability and is more structural which can help you in future to develop next project faster than before.

 

How to create section

You can create section in just few simple steps.

1. Step is to create the directory structure for your section

[theme_root]/view/sections/example/
[theme_root]/view/sections/example/view/

2. Step is to create the model and view for your section

Create a file named Example.php in [theme_root]/view/example/ with content

<?php

namespace NetLimeTheme\Sections;

use NetLimeTheme\Core\Lib\ThemeSectionBase;

class Example extends ThemeSectionBase
{
    function init()
    {
        # Set location of template / view file of section
        $this->template = dirname(__FILE__) . "/view/view.php";

        # Get some data here
        $this->data["posts"] = get_posts();
    }
}

Create a template file named view.php at [theme_root]/view/example/view/

<h4>Listing some data</h4><?php
foreach ($data["posts"] as $post) {
    echo $post->post_title . "<br/>";
}

3. Step is to update composer autoloader

In terminal/command line go to [theme_root] and type command “php composer.phar update”

Please note that in this example php accessible globally. In other case you need to modify this command with your php path.

4. Step is to register the section

Open [theme_root]/functions.php and find “### Register sections” part which should look something like this

### Register sections
add_action("on_theme_register_sections", function () {
    theme()->registerSection("Comments", new \NetLimeTheme\Sections\Comments(true));
    theme()->registerSection("Pagination", new \NetLimeTheme\Sections\Pagination(true));
    theme()->registerSection("Footer",  new \NetLimeTheme\Sections\Footer(true));
    theme()->registerSection("Header",  new \NetLimeTheme\Sections\Header(true));
    theme()->registerSection("SidebarRight", new \NetLimeTheme\Sections\SidebarRight(true));
    theme()->registerSection("SidebarLeft", new \NetLimeTheme\Sections\SidebarLeft(true));
    theme()->registerSection("Search", new \NetLimeTheme\Sections\Search(true));
    theme()->registerSection("Post", new \NetLimeTheme\Sections\Post(true));
    theme()->registerSection("PostList", new \NetLimeTheme\Sections\PostList(true));
    theme()->registerSection("NotFound", new \NetLimeTheme\Sections\NotFound(true));
    theme()->registerSection("Page", new \NetLimeTheme\Sections\Page(true));
    theme()->registerSection("Home", new \NetLimeTheme\Sections\Home(true));
    theme()->registerSection("Test", new \NetLimeTheme\Sections\Test(true));
});

Inside this hook add

theme()->registerSection("Example", new \NetLimeTheme\Sections\Example(true));

First parameter of registerSection is the section key which is unique identifier for your section and you will use it later in templates. The second parameter is the instance of your section model where the first parameter is defining if to enable cache for section or not.

Using section

To use your new section anywhere in theme you can just use theme()->renderSection(“Example”). An example:

Let’s say that you have header with logo, navigation menu and search. In that case you should have 4 sections in hierarchy like follows:

  • Header (set in template in render method)
    • Logo – set in Header’s view file using theme()->renderSection(“Logo”)
    • Navigation menu – set in Header’s view file theme()->renderSection(“MainMenu”)
    • Search – set in Header’s view file theme()->renderSection(“Search”)

But why is that good? Imagine that you have also an footer where you have same logo and navigation menu. You will create section footer and in footer’s view file you will just re-use the Logo and the Navigation menu section. So footer structure will look like follows:

  • Footer – (set in template in render method)
    • Logo – set in Footer using theme()->renderSection(“Logo”)
    • Navigation menu – set in Footer using theme()->renderSection(“MainMenu”)
    • Some other section – set in Footer  theme()->renderSection(“SomeOtherSection”)

If you need to pass some data into $this->data of section you can use theme()->renderSection(“FooBar”, [“foo” => “bar”]) and in view file use $data[“foo”] or in model use $this->data[“foo”]

But be careful with passing huge data into renderSection, since it detects that you are rendering same section on the same page with different data by using md5(json_encode($data)) which is really fast, but putting 200x WP_Post object is not smart in any way. Let’s say it will render some single article inside loop. For best results make a query where you get only ID’s and then loop these ID’s and then theme()->renderSection(“PostLoop”, [“id” => $id]);

Code example:

# Part of init method of section model for latest random articles
function init(){
    $this->template = "fooBarPathToFile";

    $latest = get_posts(array(
        'orderby' => 'rand',
        'posts_per_page' => 3,
        'fields' => 'ids'
    ));

    $this->data["latest"] = &$latest;
}

# view.php file for latest random articles
<h3>Latest posts</h3>
<?php
foreach ($latest as $id) {
    theme()->renderSection("PostLoop", ["id" => $id]);
}
?>

# Part if init method of PostLoop section
function init(){
    $this->template = "fooBarPathToFile";

    $post = get_post($this->data["id"]);

    $this->data["mypost"] = &$post;
}

# Part of view.php of PostLoop section
<article>
<h4><?= $mypost->post_title ?></h4>
<div><?= $mypost->post_excerpt ?></div>
</article>

What’s the point? you can re-use the PostLoop anywhere on the site and use with any post type. Depending on post type you can also assign different view file, while keeping section bundled as one “component”. Also you can cache each post in loop instead of the whole latest articles section. These are just two points, try imagine the possibilities!