Creating extension

I think the best way to write documentation for creating extension is by doing it on real world example.

So our example extension will add short code that can list some post type, based on shortcode arguments if any. If no arguments are specified than it will fall back to project level configuration if it exists otherwise it will fallback to extension’s default config.

Create a directory called “example” in

[theme_root]/vendor/netlime-theme

 

In this example direcoty create files:

  1. ThemeExample.php (“Theme” filename prefix is required)
  2. config.json (file name is strict;default config)
  3. composer.json (file name is strict)

 

ThemeExample.php will have content:

<?php
namespace NetLimeTheme\Extensions;

use NetLimeTheme\Core\Lib\ThemeModuleBase;

class ThemeExample extends ThemeModuleBase
{
    public function init()
    {
        add_shortcode("example_shortcode", array($this, "example_shortcode"));
    }

    /**
     * Foo bar
     */
    public function example_shortcode($args)
    {
        $config = $this->getConfig("example_shortcode");

        $posts = get_posts(array(
            "post_type" => isset($args["pt"]) ? $args["pt"] : $config["post_type"],
            "posts_per_page" => isset($args["count"]) ? $args["count"] : $config["posts_per_page"]
        ));

        if(!is_array($posts)) return "No posts found";

        $html = "<ul>";
        foreach($posts as $post) {
            $html .= "<li>" . $post->post_title . "</li>";
        }
        $html .= "</ul>";

        return $html;
    }
}

 

config.json will have content:

{
    "example_shortcode": {
        "post_type": "post",
        "posts_per_page": "-1"
    }
}

 

composer.json will have content:

{
	"name": "netlime-starter-theme/example",
	"autoload": {
		"psr-0": {
			"NetLimeTheme\\Example": ""
		}
	}
}

 

Now run composer update in theme root directory.

After composer update is done then classmaps are regenerated. Now you can register the newly created extension in your functions.php by adding it into the after_theme_autoload_modules hook right below the “### Load modules” comment.

theme()->registerModule("ThemeExample", new \NetLimeTheme\Extensions\ThemeExample());

 

Let’s test it out. Use following shortcode without the space between the “[” and the shortcode name.

[ example_shortcode pt="post" count="5"]

 

Here is the result on this website:

  • Hello world!

 

Good it works. You can use it without attributes and it will fallback to the config.json what is great, but what if you want to override the default config in project specific way?

Create folder called “example” (same name as the extension directory name) in [theme_root]/etc/ and create and create a copy of your extensions config.json here. It’s also good practice to create an empty index.php to prevent possible directory listing from browser.

[theme_root]/etc/example/config.json

 

This config.json will automatically override the one in your extension.

Let’s test it out by changing this new project level config by changing the post type defined to “page” then use following shortcode without the space between the “[” and the shortcode name to test if it will list 5 pages.

[ example_shortcode count="5"]

 

Here is the result on this website:

  • Blog
  • Installing extension
  • Overriding extension
  • Creating extension
  • Extensions

 

Congratulations! You just made a reusable, easy to debug theme extension, that supports local, project level and default configuration.

These things that we made here are just really basic things. You can check out for example the ThemeCache extension which will show you more advanced usage.

In extensions you can basically do whatever you want. Just few examples:

  1. Create custom post types, database tables,…
  2. Create install scripts (for example if theme has no file called template-xYZ.php that is required by your module, you can generate or copy it into theme root)
  3. Overriding other modules
  4. Creating sections with the same way like described in the 2. point.
  5. Creating preconfigured PDF extension with some library that you anytime just copy into your project and you don’t need to implement it from scratch every time on every project
  6. Adding some custom fields framework to your theme…