Developing a plugin using DI and TDD 05

Time to actually print something on the page.

The quick approach I did not take

I’ve got a class responsible for the rendering of an extremely trivial shortcode that’s not printing nothing on the page.
I’ve gone into a lot of thought before each step in the development process(see the previous article and the ones before that) and what could have been something as simple as this

public function render()
{
    return '<button class="idlikethis">' . __("I'd like this", 'idlikethis') . '</button>';
}

has escalated.

The overkill and DRYer approach

The pain I took to set up and scaffold a scalable structure is not paying off in the small scale: but it’s always easier to reduce than to augment when it comes to coding and I’m trying, after all, to leverage the dependency injection possibilities DI52 offers as much as possible.
So I’ve got a template engine in place, namely Smarty, and some code ready to use it in the idlikethis_Shortcodes_Simple::render method

public function render()
{
    return $this->render_engine->render($this->template_slug, $this->template_data);
}

The button template itself is trivial

<span class="idlikethis-button idlikethis-button--simple">
    <button class="idlikethis-button__button">
        <span class="idlikethis-button__text">{$text}</span>
    </button>
</span>

but what is not is the consideration about the addition of the idlikethis_Texts_ProviderInterface dependency to the idlikethis_Shortcodes_Simple class:

<?php

class idlikethis_Shortcodes_Simple implements idlikethis_Shortcodes_ShortcodeInterface
{
    /**
     * @var string
     */
    protected $template_slug;

    /**
     * @var array
     */
    protected $template_data;

    /**
     * @var idlikethis_Templates_RenderEngineInterface
     */
    protected $render_engine;

    /**
     * @var idlikethis_Texts_TextProviderInterface
     */
    protected $text_provider;

    /**
     * @param idlikethis_Templates_RenderEngineInterface $render_engine
     * @param idlikethis_Texts_ProviderInterface $text_provider
     */
    public function __construct(idlikethis_Templates_RenderEngineInterface $render_engine, idlikethis_Texts_ProviderInterface $text_provider)
    {
        $this->render_engine = $render_engine;
        $this->template_slug = 'shortcodes/simple';
        $this->text_provider = $text_provider;
        $this->template_data = array(
            'text' => $this->text_provider->get_button_text(),
        );
    }

    //more methods here... 

    /**
     * Returns the shortcode rendered markup code.
     *
     * @return string
     */
    public function render()
    {
        return $this->render_engine->render($this->template_slug, $this->template_data);
    }
}

Why is that?

Scaling

As has been the case until now this approach is more complex than the current application would require.
What seems now useless complication might pay off thinking ahead: at the moment the button is using just a line of text (“I’d like this”) that, even willing to inject everything, might be passed in a string dependency.
But what about adding some accessibility? Would it not require additional text? Or a graceful fallback for non JavaScript enabled browsers and hence a url? The construct method might end up like this:

public function __construct(idlikethis_Templates_RenderEngineInterface $render_engine, $text, $title, $fallback_url, $css)
{
    // ...
}

And so on.
Injecting one or more classes in charge of that will keep the code cleaner and more maintainable.
What the idlikethis_Texts_Provider class does is easy to understand

<?php

class idlikethis_Texts_Provider implements idlikethis_Texts_ProviderInterface
{

    /**
     * Returns the localized version of the button text.
     *
     * @return string
     */
    public function get_button_text()
    {
        return __("I'd like this", 'idlikethis');
    }
}

It works. To a point.

The shortcode plugin is now working and it’s time to have it hosted on GitHub for the code to be looked into.
Next iteration will be to have the button do something and “call home”.