Your Widget

Project on Github

Your Widget is a code framework for fast and easy development of new wordpress widgets. It has all the necessary methods implemented, and Twig is loaded and setup and ready for templating.

The idea is built on a three step process.

Define your data

Your have to defined the type of data you want your widget to contain. The method for this is somewhat inspired by the drupal form API where you define your fields in an array. The structure is as follows.

$fields => [
    // Machine name is just an unique array key
    'field_machine_name' => [
        'label' => 'The label visible to users',
        'type' => 'input type',
        // Options are only used for checkboxes and radio buttons
        'options' => [
            'label' => 'The label visible to users. Overrides previous label',
            'value' => 'Unique value to identify selected option',
        ]
    ]
]

The title and template_file are added by the plugin. Real world example below.

function modify_widget_fields($fields, $widget_id) {
    $fields = [
        'number_of_posts' => [
            'label' => 'Number of posts',
            'type' => 'number',
        ],
        'category' => [
            'label' => 'Category',
            'type' => 'radio',
            'options' => [
                'popular' => [
                    'label' => 'Popular posts',
                    'value' => 'popular',
                ],
                'recent' => [
                    'label' => 'Recent posts',
                    'value' => 'recent',
                ],
                'similar' => [
                    'label' => 'Similar posts',
                    'value' => 'similar',
                ]
            ]
        ]
    ];
}
add_filter('your_widget_fields', 'modify_widget_fields', 10, 2);

Setup your template data

There’s a filter which allows you to add your own template data. Say you’ve saved an post id in one of your widget fields. You can now use your filter to load tthe post and add its data to the template.

add_filter('your_widget_tmpl_data', function ($tmplData$, $widget_id) {
    $tmplData['post'] = (array) get_post($tmplData['id']);

    return $tmplData;
}, 10, 2);

Design output

Finally design the output by adding a template file in the theme root directory. Your Widget uses Twig as template engine. You find the documentation here. Simple example below where I’ve added post data to the template data array.

{{before_widget}}
    {{before_title}}
        <h2>{{post.post_title}}</h2>
        <div class="content">
            {{post.post_content}}
        </div>
        <a href="{{post.permalink}}">Read more</a>
    {{after_title}}
{{after_widget}}

Help and more info

That’s about it. Good luck and let me know if I can help you with anything <3

Perfect Excerpt

Project on Github

Perfect Excerpt is a WordPress plugin that shortens your excerpts to whole sentences. It will break the text on the punctuation closest to the length specified. Set the excerpt length by adding the row below to functions.php. Valid break positions are dots, question marks and exclamation mark.

update_option('excerpt_length', 300);

The number 300 in this case is the maximum number of words that will be shown.

To bypass Perfect Excerpt you can get the full excerpt by using the $post object.

$post->post_excerpt;

Add this option to overside auto init.

update_option('perfect_excerpt_disable_auto_init', true);

Happy writing!

WordPress Option Page Helper

Project on Github

I thought I was a bit complicated to add option pages so I wrote a helper that simplify thing a bit. The helper stores recurring variables like page slug so you don’t have to pass it with all function calls. It created callback automatically based on the section or field name, so you don’t have to care about that eigher. This is a simple example on how to create a options page

$options = array(
    'page_title' => 'Settings Admin',                   // Page title
    'menu_title' => 'My Settings',                      // Menu title
    'capability' => 'manage_options',                   // Capability
    'menu_slug' => 'my-settings',                       // Menu slug
    'callback' => array($this, 'page'),                 // Callback object
    'form' => array(
        array(
            'name' => 'First Section',                  // Section name
            'fields' => array(
                'first_option' => 'First option'        // Field id and name
            )
        )
    ),
);

$this->optionPageHelper = new OptionPageHelper($options);

You’re page is created, but there are some callbacks to take care of.

/**
 * Options page callback.
 *
 * This is where you add everything you want to the page.
 * The form with all your settings is generated automatically
 * when renderForm() is called.
 */
public function page()
{
    $output = '
        <div class="wrap">
            <h2>My Option Page</h2>
            ' . $this->optionPageHelper->renderForm() . '
        </div>
    ';

    echo $output;
}

And then we have the field(s) callback…

/**
 * Callback for an option field.
 *
 * The field callback will be generated automatically based on the id of your field.
 * If your field id is first_option, the callback will be firstOptionFieldCallback.
 *
 * The option key for your setting will also be generated automatically.
 * It will be prefixed with the menu_slug in your options array.
 * first_option will be saved as my-settings_first_option.
 */
public function firstOptionFieldCallback()
{
    // Get saved field values
    $option = get_option('my-settings_first_option');

    // Build element and print
    echo '<input name="my-settings_first_option" value="' . $option . '">';
}

Don’t forget to read the code comments here, they’re useful.

The Utils class contains some formatting helpers, so you need that file to. The OptionPage class is just an example on how to implement this, just like this readme.

Mustache PHP JS – For WordPress

Project on Github

I had the pleasure of working with a really talented developer on my previous job. He is the most pedantic developer I’ve ever met and he had some really nice solutions to most of our problems. One of the nice solutions was how he integrated and shared mustache templates between php and javascript. I have recently been in projects where this has been requested so I copies his design and wrote my own mustache plugin for wordpress.

More info about mustache on mustache.github.io
and sitepoint.com

PHP

This is an example of how it can look in your html template file.

<div class="panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">Mustache Example</h3>
    </div>
    <div class="panel-body feed">
        <?php mustache()->capture(); ?>
            <div class="col-sm-3">
                <a href="{{permalink}}">
                    <img src="{{image}}">
                    <h3 class="title">{{title}}</h3>
                    <small>{{date}}</small>
                    <div class="excerpt">{{excerpt}}</div>
                </a>
            </div>
        <?php mustache()->render('postTmpl', getTmplData()); ?>
    </div>
    <?php mustache()->getScript(); ?>
    <a class="load" href="#">Load more posts</a>
</div>

You can call the mustache() function as soon as the plugin is active. This will return the mustache object for you. Call the capture() function at the top of the code that you want to be a part of your template. This will start the PHP output buffer and save all code within your template to a string. At the end of your template you call render(). This will stop the output buffer as well as output the template with the passed template data.

You probably want to get your template data from a function if your going to use mustache.js since you will be loading your data with ajax. If you’re not going to use mustache.js there’s not much more to it.

function getTmplData()
{
    // Load your data and return a nicely formatted array
    $tmplData = [
        'title' => 'First post',
        'permalink' => 'http://your-site.com/first-post',
        'image' => 'image-1.jpg',
        'date' => '2025-01-01',
        'excerpt' => 'This is a future post',
    ];

    return $tmplData;
}
add_action('wp_ajax_get_tmpl_data', 'getTmplData');
add_action('wp_ajax_nopriv_get_tmpl_data', 'getTmplData');

Javascript

Outside of your wrapper div you have to call the getScript() function. This will output the template code wrapped in script tags for mustache.js to use. Use the ID of the script to get the html in it and pass that to Mustache.render together with your template data. Last step is to append (or maybe replace) the new content.

$('a#load').click(function(e) {
    e.preventDefault();

    // Get this data from your php function
    var tmplData = {
        'title' => 'Second post',
        'permalink' => 'http://your-site.com/second-post',
        'image' => 'image-2.jpg',
        'date' => '2225-01-01',
        'excerpt' => 'This... is not going to happen',
    };

    var output = Mustache.render($('#postTmpl').html(), tmplData);
    $('.wrapper').append(output);
});

Partials

Define your partials like this…

<?php mustache()->capture(); ?>
    {{#posts}}
        <div class="col-sm-3">
            <a href="{{permalink}}">
                {{{post_thumbnail}}}
                <h3>{{post_title}}</h3>
                <small>{{date}}</small>
                <div>{{excerpt}}</div>
            </a>
        </div>
    {{/post}}
<?php mustache()->setPartial('postPartial')->getScript(); ?>

… and use it like this

<?php mustache()->capture(); ?>
    {{>post_partial}}
<?php mustache()->render('postTmpl', getTmplData()); ?>

This will generate the same output as the first example, but now you can reuse your postPartial. An example using partials in javascript could look something like this.

var template = $('#postTmpl').html();
var partials = {postPartial: $('#postPartial').html()};
$.post(ajax.url, data, function(response) {
    var output = Mustache.render(template, response, partials);
    $('.wrapper').append(output);
});

Simple Post Preview

Project on Github

Simple Post Preview is a widget that creates pushes for your posts.

Description

Simple Post Preview can create two kinds of pushes. The first is a static push for any post or page. The second one is for categories where the widget automatically shows the latest post in a category.

Set it up

Not really a lot to do here except select the content types you want the plugin to work with on the Simple Post Preview settings page.

Customization

The GUI of this plugin is pretty straight forward so I just right to the more interesting parts. As of version 2.0 I’ve implemented Twig as template engine and added the feature for designers and developers to use their own templates with Simple Post Preview. In every widget you have a field to add then name of your html template file in the root of your theme folder. Below is an array of all the variables available in the template. If you’re not sure how to use Twig, have a look at this introduction page.

$tmplData = array (
    'name' => 'Primary Sidebar',
    'id' => 13,
    'description' => 'Main sidebar that appears on the left.',
    'class' => '',
    'before_widget' => '<aside id="simple_post_preview-13" class="widget widget_simple_post_preview">',
    'after_widget' => '</aside>',
    'before_title' => '<h1 class="widget-title">',
    'after_title' => '</h1>',
    'widget_id' => 'simple_post_preview-13',
    'widget_name' => 'Simple Post Preview',
    'title' => 'It\'s simple!',
    'item_id' => '5919',
    'item_type' => 'post',
    'content_type' => 'body',
    'thumbnail_switch' => 'on',
    'thumbnail_size' => 'medium',
    'length' => '200',
    'link_title' => 'Read more',
    'show_categories' => 'on',
    'template' => 'my-custom-widget-template.html',
    'ID' => 5919,
    'post_author' => '1',
    'post_date' => '2014-07-15 08:06:56',
    'post_date_gmt' => '2014-07-15 08:06:56',
    'post_content' => 'Lorem ipsum dolor sit amet...',
    'post_title' => 'This is simple post preview',
    'post_excerpt' => 'Lorem ipsum...',
    'post_status' => 'publish',
    'comment_status' => 'open',
    'ping_status' => 'open',
    'post_password' => '',
    'post_name' => 'this-is-simple-post-preview',
    'to_ping' => '',
    'pinged' => '',
    'post_modified' => '2014-07-15 08:17:49',
    'post_modified_gmt' => '2014-07-15 08:17:49',
    'post_content_filtered' => '',
    'post_parent' => 0,
    'guid' => 'http://your-site.dev/?p=5919',
    'menu_order' => 0,
    'post_type' => 'post',
    'post_mime_type' => '',
    'comment_count' => '0',
    'filter' => 'raw',
    'content' => 'Lorem ipsum dolor sit amet...',
    'permalink' => 'http://your-site.dev/this-is-simple-post-preview/',
    'categories' =>
    array (
        0 => array (
            'term_id' => 38,
            'name' => 'Plugins',
            'slug' => 'plugins',
            'term_group' => 0,
            'term_taxonomy_id' => 38,
            'taxonomy' => 'category',
            'description' => '',
            'parent' => 0,
            'count' => 1,
            'filter' => 'raw',
            'cat_ID' => 38,
            'category_count' => 1,
            'category_description' => '',
            'cat_name' => 'Plugins',
            'category_nicename' => 'plugins',
            'category_parent' => 0,
            'url' => 'http://your-site.dev/category/plugins/',
        ),
    ),
    'featured_image' => array (
        'width' => 327,
        'height' => 683,
        'file' => '2014/07/screenshot-1.png',
        'sizes' => array (
            'thumbnail' => array (
                'file' => 'screenshot-1-80x80.png',
                'width' => 80,
                'height' => 80,
                'mime-type' => 'image/png',
            ),
            'medium' => array (
                'file' => 'screenshot-1-143x300.png',
                'width' => 143,
                'height' => 300,
                'mime-type' => 'image/png',
            ),
            'post-thumbnail' => array (
                'file' => 'screenshot-1-327x372.png',
                'width' => 327,
                'height' => 372,
                'mime-type' => 'image/png',
            ),
            'twentyfourteen-full-width' => array (
                'file' => 'screenshot-1-327x576.png',
                'width' => 327,
                'height' => 576,
                'mime-type' => 'image/png',
            ),
        ),
        'image_meta' => array (
            'aperture' => 0,
            'credit' => '',
            'camera' => '',
            'caption' => '',
            'created_timestamp' => 0,
            'copyright' => '',
            'focal_length' => 0,
            'iso' => 0,
            'shutter_speed' => 0,
            'title' => '',
        ),
        'thumbnail_url' => 'http://your-site.dev/wp-content/uploads/2014/07/screenshot-1-80x80.png',
        'medium_url' => 'http://your-site.dev/wp-content/uploads/2014/07/screenshot-1-143x300.png',
        'large_url' => 'http://your-site.dev/wp-content/uploads/2014/07/screenshot-1.png',
        'post-thumbnail_url' => 'http://your-site.dev/wp-content/uploads/2014/07/screenshot-1-327x372.png',
        'twentyfourteen-full-width_url' => 'http://your-site.dev/wp-content/uploads/2014/07/screenshot-1-327x576.png',
    ),
    'show_image' => true,
    'image_url' => 'http://your-site.dev/wp-content/uploads/2014/07/screenshot-1-143x300.png',
    'excerpt_more' => ''
);

I’ve added a hook that allows you to customize the template data.

    add_filter('simple_post_preview_tmpl_data', function ($tmplData) {
        // Modify the $tmplData array here
        return $tmplData;
    });

Feel free to ask questions or help out, both on wordpress.org and github.