Adding a Custom TV Type - MODX 2.2
Last edited by Patrick Percy Blank on Sep 3, 2013.
What are Custom TV Input Types?
MODx Revolution allows you to create your own custom TV input types (similar to the textbox, radio, textarea, richtext, etc types already available) for your Template Variables. This tutorial will show a very simple example by loading a simple Template dropdown for us in the mgr, and then in the frontend will render our Template ID wrapped in a special div. We'll call it "TemplateSelect". We'll also make this an Extra called "OurTVs", meaning that we'll have the files outside of the normal TV input renders directory, and put it in our own Extra's directory in core/components/ourtvs/.
Create a Namespace
If you haven't already, go ahead and create a Namespace called "ourtvs" with the path "{core_path}components/ourtvs/". This will help us later on.
Creating the Pathing Plugin
We'll need a plugin to tell MODX where our custom TV directories are. Go ahead and make a plugin called "OurTvsPlugin", and assign it to the following events:
- OnTVInputRenderList - For rendering the actual TV input in the backend
- OnTVOutputRenderList - For rendering the TV output in the frontend
- OnTVInputPropertiesList - For loading any custom properties for the input render in the manager
- OnTVOutputRenderPropertiesList - For loading any custom properties for the output render (front-end) of the TV
- OnDocFormPrerender - For loading any custom JS/CSS for our TV
Now put in the Plugin code:
$corePath = $modx->getOption('core_path',null,MODX_CORE_PATH).'components/ourtvs/'; switch ($modx->event->name) { case 'OnTVInputRenderList': $modx->event->output($corePath.'tv/input/'); break; case 'OnTVOutputRenderList': $modx->event->output($corePath.'tv/output/'); break; case 'OnTVInputPropertiesList': $modx->event->output($corePath.'tv/inputoptions/'); break; case 'OnTVOutputRenderPropertiesList': $modx->event->output($corePath.'tv/properties/'); break; case 'OnManagerPageBeforeRender': break; }
These event handlers tell MODX to check these directories for our TV files when doing all the rendering and processing. Think of it like adding library or include paths.
Creating the Input Controller
The input controller is what actually loads the markup for the custom TV input. Create the input controller file here:
core/components/ourtvs/tv/input/templateselect.class.php
And inside, you can put this code:
<?php if(!class_exists('TemplateSelectInputRender')) { class TemplateSelectInputRender extends modTemplateVarInputRender { public function getTemplate() { return $this->modx->getOption('core_path').'components/ourtvs/tv/input/tpl/templateselect.tpl'; } public function process($value,array $params = array()) { } } } return 'TemplateSelectInputRender';
Here we tell it where to find our smarty template for rendering the TV, as well as having a process() method to do any business logic we want to do prior to rendering the TV.
Now you can see here we are specifying a "tpl" file for rendering our TV. Go ahead and put it here:
core/components/ourtvs/tv/input/tpl/templateselect.tpl
And make its content:
<select id="tv{$tv->id}" name="tv{$tv->id}" class="combobox"></select> <script type="text/javascript"> // <![CDATA[ {literal} MODx.load({ {/literal} xtype: 'modx-combo-template' ,name: 'tv{$tv->id}' ,hiddenName: 'tv{$tv->id}' ,transform: 'tv{$tv->id}' ,id: 'tv{$tv->id}' ,width: 300 ,value: '{$tv->value}' {literal} ,listeners: { 'select': { fn:MODx.fireResourceFormChange, scope:this}} }); {/literal} // ]]> </script>
And that should render us a nice template dropdown in the backend:
Creating the Output Controller
Okay, so now we want to make the output controller, let's create the file at:
core/components/ourtvs/tv/output/templateselect.class.php
And the content:
if(!class_exists('TemplateSelectOutputRender')) { class TemplateSelectOutputRender extends modTemplateVarOutputRender { public function process($value,array $params = array()) { return '<div class="template">'.$value.'</div>'; } } } return 'TemplateSelectOutputRender';
There we go - now when we render this in the front-end, it will display the ID of our selected Template wrapped in a div.
See Also
- Creating a Template Variable
- Bindings
- Template Variable Input Types
- Template Variable Output Types
- Adding a Custom TV Type - MODX 2.2
- Adding a Custom TV Input Type
- Adding a Custom TV Output Type
- Creating a multi-select box for related pages in your template
- Accessing Template Variable Values via the API
Suggest an edit to this page on GitHub (Requires GitHub account. Opens a new window/tab).