English plugin dev 2 3

semuel edited this page Jan 16, 2012 · 9 revisions

Developing Conditional Tags Plugins

What are conditional Tags?

Examples for built-in conditional tags: <MTIf><MTIfBlog><MTIfCategory>

Also, conditional tags can support an ‘else’ case: <MTIfBlog>〜<MTElse>〜</MTIfBlog>

Conditional tags are the ‘if’ of the Movable Type template language, and make it possible to change the output in response to a variety to cases.

As in block tags, (which conditional tags are a special case of) the PHP and Perl implementation differs quite a bit

Example Plugin specification and tests

Plugin Usage

  • Tag name: <MTCategoryIfToplevel>
  • For usage in the blog achive tamplates
  • Should be negative if the entry does not have a category associated
  • Should be positive if the category is top-level
  • Should have an ‘else’ case. example:
<MTCategoryIfToplevel>
<p>This entry is set to a top-level category</p>
<MTElse>
<p>This entry either does not have a category set or the category is not top-level</p>
</MTCategoryIfToplevel>
  • In the above example, if positive <p>This entry is set to a top-level category</p> will appear
  • In the above example, if negative <p>This entry either does not have a category set or the category is not top-level</p> will appear

Test Case: 00-compile.t

Verify that each module loads OK

use strict;
use lib qw( t/lib lib extlib );
use warnings;
use MT;
use Test::More tests => 5;
use MT::Test;

ok(MT->component ('MyPlugin07'), "MyPlugin07 plugin loaded correctry");

require_ok('MyPlugin07::L10N');
require_ok('MyPlugin07::L10N::ja');
require_ok('MyPlugin07::L10N::en_us');
require_ok('MyPlugin07::Tags');

1;

Test Case: 01-tags.t

We want to test three cases:

  1. For empty string we should get an empty response
  2. For entry that have a top-level category, we should get “AAA
  3. For entry that does not, we should get “BBB
... snip ...
#===== Edit here
my $test_json = <<'JSON';
[
{ "r" : "1", "t" : "", "e" : ""},
{ "r" : "1", "t" : "<mt:Entries id=\"6\"><MTCategoryIfToplevel>AAA<MTElse>BBB</MTCategoryIfToplevel></mt:Entries>", "e" : "AAA"},
{ "r" : "1", "t" : "<mt:Entries id=\"8\"><MTCategoryIfToplevel>AAA<MTElse>BBB</MTCategoryIfToplevel></mt:Entries>", "e" : "BBB"}
]
JSON
#=====
... snip ...

Conditional Tag Plugin Development (Perl)

We will base our example on MyPlugin6 that was written in the previous chapter

config.yaml

The declaration of this tag is identical to a block tag, but it contains a ‘?’ in the end, marking it as a conditional tag instead of a normal block tag

id: MyPlugin07
name: <__trans phrase="Sample Plugin Conditional tag">
version: 1.0
description: <__trans phrase="_PLUGIN_DESCRIPTION">
author_name: <__trans phrase="_PLUGIN_AUTHOR">
author_link: http://www.example.com/about/
doc_link: http://www.example.com/docs/
l10n_class: MyPlugin07::L10N

tags:
    block:
        CategoryIfToplevel?: $MyPlugin07::MyPlugin07::Tags::hdlr_category_if_toplevel

L10N.pm

package MyPlugin07::L10N;
use strict;
use base 'MT::Plugin::L10N';

1;

L10N/en_us.pm

package MyPlugin07::L10N::en_us;

use strict;
use base 'MyPlugin07::L10N';
use vars qw( %Lexicon );

%Lexicon = (
    '_PLUGIN_DESCRIPTION' => 'Sample conditional tag',
    '_PLUGIN_AUTHOR' => 'Plugin author',
);

1;

L10N/ja.pm

package MyPlugin07::L10N::ja;

use strict;
use base 'MyPlugin07::L10N::en_us';
use vars qw( %Lexicon );

%Lexicon = (
    'Sample Plugin Conditional tag' => 'サンプルプラグイン コンディショナルタグ',
    '_PLUGIN_DESCRIPTION' => ' テストプラグイン',
    '_PLUGIN_AUTHOR' => 'プラグイン作者',
);

1;

Tags.pm

package MyPlugin07::Tags;
use strict;

sub hdlr_category_if_toplevel {
    my ($ctx, $args, $cond) = @_;

    my $entry = $ctx->stash('entry');
    my $cat = $entry->category() || return 0;

    return ($cat->parent() == 0);
}

1;

Commentary

  • Package Declaration
    Package Declaration and of course, “use strict”

  • Tag handler declaration
    Function that the template engine will call when seeing a <MTCategoryIfToplevel> tag. it gets the context ($ctx) and the tags arguments ($args) as parameters

  • Retrieving objects from the context
    In line 7, it gets the current entry from the context, and then (in line 8) the main entry’s category.
    If no main entry is set, returns 0 – mean negative

  • Final Test
    Check the main category’s parent category. If 0, means that the category has no parent => it is a top-level => return positive. otherwise, return negative

Conditional Tag Plugin Development (PHP)

block.mtcategoryiftoplevel.php

A conditional tag is a variant of a block tag, so we use the block tag file naming convention, and for the <MTCategoryIfToplevel> tag we use block.mtcategoryiftoplevel.php

<?php
    function smarty_block_mtcategoryiftoplevel ($args, $content, &$ctx, &$repeat) {
        if (!isset($content)) {
            $entry = $ctx->stash('entry');
            $cat = $entry->category();
            if (!$cat) {
                $flag = 0;
            } else {
                if ($cat->parent == 0) {
                    $flag = 1;
                } else {
                    $flag = 0;
                }
            }
            return $ctx->_hdlr_if($args, $content, $ctx, $repeat, $flag);
        } else {
            return $ctx->_hdlr_if($args, $content, $ctx, $repeat);
        }
    }
?>

Commentary

  • handler declaration
    As the block tag, according the the smarty notation, the function name for <MTCategoryIfToplevel> is smarty_block_mtcategoryiftoplevel, and receive four parameters: “$args”, “$content”, “$ctx” and “$repeat”

  • Testing the condition
    As explained in the block-tag chapter, the $content variable is not set on the first time that the function is called for a block (that is before the block is processed) and set on the next time.
    In both cases, we hand off the actual block handling to the helper function $ctx->_hdlr_if(). it does the ‘else’ handling for us.
    If this is the first time, ($content is unset) we get the entry from the context, and check the main category, as was done in the Perl side. And we pass the results to _hdlr_if as an extra parameter.
    On the second time, we just call _hdlr_if. presumably it saved everything it needs to know inside $ctx

Directory Structure

$MT_DIR/
|__ plugins/
   |__ MyPlugin07/
      |__ config.yaml
      |__ lib/
      |  |_ MyPlugin07/
      |     |__ L10N.pm
      |     |_ L10N/
      |     |  |_ en_us.pm
      |     |  |_ ja.pm
      |     |_ Tags.pm
      |__ php/
      |  |_block.mtcategoryiftoplevel.php
      |__ t/
         |_00-compile.t
         |_01-tags.t

Testing the Plugin

Running the tests with prove

$ prove plugins/MyPlugin07/t/*.t
plugins/MyPlugin07/t/00-compile.t .. ok   
plugins/MyPlugin07/t/01-tags.t ..... ok   
All tests successful.
Files=2, Tests=12, 29 wallclock secs ( 0.08 usr  0.07 sys + 15.45 cusr  4.73 csys = 20.33 CPU)
Result: PASS

Now that the tests ran, we can try it out by putting this tag inside the “<div id=”alphe-inner">" HTML tag, in the entries template

  • Template
... snip ...
<div id="alpha">
  <div id="alpha-inner">
    <MTCategoryIfToplevel>
    <p>This entry is of a top-level category</p>
    <MTElse>
    <p>This entry either does not have a category set, or the category is not top-level</p>
    </MTCategoryIfToplevel>
... snip ...
  • Output
... snip ...
<div id="alpha">
  <div id="alpha-inner">

    <p>This entry is of a top-level category</p>
... snip ...

Summary

Ummm…. tags are fun? :-)

Plugin Download

MyPlugin07.zip(5.98KB)

Navigation

Prev:Developing Block-Tag Plugins << Index >> Next:Plugin Debugging

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.