MODX Cloud

The Most Productive MODX Learning Playground Ever

Claim Free Lab Account

Adding a Custom TV Output Type

Skip to end of metadata
Go to start of metadata
Only use this documentation for pre-2.2 or core submissions.
Refer to the Adding a Custom TV Type doc for the proper way to build custom TVs in 2.2 which allows easy packaging.

What are TV Output Types?

TV Output Types allow you to output Template Variables in different markup and formats. Some examples include outputting a TV value as an image, URL, HTML tag, date, etc.

MODx Revolution lets you create custom output types fairly easily.

Creating the Files

Let's create a custom TV Output Type called "button". This will render an input button (or more than one) with a specified value and an optional name, with some other fields for attributes. You'll need 3 files:

  • An input properties controller - put here: core/model/modx/processors/element/tv/renders/mgr/properties/button.php
  • An input properties template - put here: manager/templates/default/element/tv/renders/properties/button.tpl
  • An output controller - put here: core/model/modx/processors/element/tv/renders/web/output/button.php

Setting up the Input Properties Controller

This is the PHP file that will load the mgr template for managing the TV output type's properties. We'll have it contain just this:

<?php
// any custom php you want to run here
return $modx->smarty->fetch('element/tv/renders/properties/button.tpl');

Setting up the Input Properties Template

This is the template for the default manager theme to render properties with. We'll use ExtJS to render some pretty form fields:

<div id="tv-wprops-form{$tv}"></div>
{literal}
<script type="text/javascript">
// <![CDATA[
var params = {
{/literal}{foreach from=$params key=k item=v name='p'}
 '{$k}': '{$v}'{if NOT $smarty.foreach.p.last},{/if}
{/foreach}{literal}
};
var oc = {'change':{fn:function(){Ext.getCmp('modx-panel-tv').markDirty();},scope:this}};
MODx.load({
    xtype: 'panel'
    ,layout: 'form'
    ,autoHeight: true
    ,labelWidth: 150
    ,border: false
    ,items: [{
        xtype: 'textfield'
        ,fieldLabel: _('class')
        ,name: 'prop_class'
        ,id: 'prop_class{/literal}{$tv}{literal}'
        ,value: params['class'] || ''
        ,width: 300
        ,listeners: oc
    },{
        xtype: 'textfield'
        ,fieldLabel: _('id')
        ,name: 'prop_id'
        ,id: 'prop_id{/literal}{$tv}{literal}'
        ,value: params['id'] || ''
        ,width: 300
        ,listeners: oc
    },{
        xtype: 'textfield'
        ,fieldLabel: _('style')
        ,name: 'prop_style'
        ,id: 'prop_style{/literal}{$tv}{literal}'
        ,value: params['style'] || ''
        ,width: 300
        ,listeners: oc
    },{
        xtype: 'textfield'
        ,fieldLabel: _('attributes')
        ,name: 'prop_attributes'
        ,id: 'prop_attributes{/literal}{$tv}{literal}'
        ,value: params['attributes'] || ''
        ,width: 300
        ,listeners: oc
    }]
    ,renderTo: 'tv-wprops-form{/literal}{$tv}{literal}'
});
// ]]>
</script>
{/literal}

The key way these save is that each field is prepended with 'prop_' in its name. This tells MODx to save this field in the TV's output properties. Make sure you specify your fields with this prefix!

You don't have to use ExtJS, however - you can use just straight HTML - it's totally up to you.
Note that if you created another manager theme, you'd have to create a properties tpl for that theme as well.

Setting up the Output Controller

Now we get into the good stuff. This controller will handle exactly how the button is outputted. Our file looks like this (comments inline):

<?php
$o= '';
$buttons= $this->parseInput($value, '||', 'array');
/* allow multiple buttons separated by ||, or checkbox/multiple input tvs */
foreach ($buttons as $button) {
    if (!is_array($button)) {
        $button= explode('==', $button);
    }
    /* the TV value must have a value of either: text or text==name */
    $text = $button[0];
    if (!empty($text)) {
        $attributes = '';
        $attr = array(
            'class' => $params['class'],
            'id' => ($params['id'] ? $params['id'] : ''),
            'alt' => htmlspecialchars($params['alttext']),
            'style' => $params['style']
        );
        /* if a name is specified, use it! */
        if (!empty($button[1])) $attr['name'] = $button[1];

        /* separate the attributes into html tag format */
        foreach ($attr as $k => $v) $attributes.= ($v ? ' '.$k.'="'.$v.'"' : '');
        $attributes .= ' '.$params['attrib'];

        /* Output the image with attributes */
        $o .= '<button'.rtrim($attributes).'>'.$text.'</button>'."\n";
    }
}

return $o;

Using the Custom TV Output Type

So, how does it look? Well, it should render an output form like this when editing the TV - I've added some custom values to it as well:

So we'll save this, and then let's go edit in in a Resource. We'll specify two buttons, separating with ||. We could also just do one button. And, we'll have the first button have a custom 'name' attribute as well:

Great. Now let's preview the resource, and we'll get an output like this:

And we can examine the HTML source:

And there you go! A custom TV output type!

See Also

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.