This is a fantastic addition to MODx and a must have. We have been using MIGx for territory specific page translations and also for filtering output by one of the input fields e.g. output the contact numbers for simplified chinese
I thought I would share what we have done and see if it is useful to further enhance an already excellent addon. The following snippets of code are based on the MIGx addon and are geared towards translations of a single Document Resource.
For the filtering of the results, we created a "getFilteredList" snippet based on the "getImageList" snippet, the code is as follows:
<?php
// [[!getFilteredList? &tvname=`t_metaContent` &tpl=`chunkName` &docid=`[[+id]]` &filterBy=`tcode` &filterValue=`ar` ]]
$tvname = $modx->getOption('tvname', $scriptProperties,'');
$tpl = $modx->getOption('tpl', $scriptProperties, '');
$docid = $modx->getOption('docid', $scriptProperties,$modx->resource->get('id'));
$limit = $modx->getOption('limit', $scriptProperties, '0');
$offset = $modx->getOption('offset', $scriptProperties, 0);
$filterBy = $modx->getOption('filterBy', $scriptProperties, ''); // Name of the field to filter by
$filterValue = $modx->getOption('filterValue', $scriptProperties, ''); // The value of the filterBy field
$debug = $modx->getOption('debug', $scriptProperties, '');
$displayLang = isset($_SESSION['session_lang_display_setting']) ? $_SESSION['session_lang_display_setting'] : 'en'; // get the custom language session code
$hasTCode = false;
if (empty($tpl)) return 'empty property: &tpl';
if (!empty($tvname)) {
if ($tv = $modx->getObject('modTemplateVar', array('name' => $tvname))) {
$outputvalue = $tv->renderOutput($docid);
/*
* get inputTvs
*/
$properties = $tv->get('input_properties');
$properties = isset($properties['columns']) ? $properties : $tv->getProperties();
$formtabs = $modx->fromJSON($properties['formtabs']);
$inputTvs = array();
if (is_array($formtabs)) {
foreach ($formtabs as $tab) {
if (isset($tab['fields'])) {
foreach ($tab['fields'] as $field) {
if (isset($field['inputTV'])) {
$inputTvs[$field['field']] = $field['inputTV'];
}
}
}
}
}
}
}
if (empty($outputvalue)) return '';
$tempItems = $modx->fromJSON($outputvalue);
$items = array();
if(!empty($filterBy) && !empty($filterValue)){
foreach($tempItems as $item)
{
if($item[$filterBy] == $displayLang)
{
array_push($items,$item);
}
}
}
else
{
$items = $tempItems;
}
//$items = $modx->fromJSON($outputvalue);
$limit = $limit == 0 ? count($items) : $limit;
$output = '';
if (substr($tpl, 0, 6) == "@FILE:")
{
$template = file_get_contents($modx->config['base_path'] . substr($tpl, 6));
}
else
{
if (substr($tpl, 0, 6) == "@CODE:")
{
$template = substr($tpl, 6);
}
else
{
if ($chunk = $modx->getObject('modChunk', array('name' => $tpl), true))
{
$template = $chunk->getContent();
}
else
{
$template = false;
}
if ($template)
{
if (count($items) > 0)
{
$idx = 0;
foreach ($items as $key => $item)
{
$fields = array();
foreach ($item as $field => $value)
{
if (isset($inputTvs[$field]))
{
if ($tv = $modx->getObject('modTemplateVar', array('name' => $inputTvs[$field])))
{
$tv->set('default_text', $value);
$fields[$field] = $tv->renderOutput($docid);
}
}
else
{
$fields[$field] = $value;
}
}
$doFilter = ( !empty($filterBy) && !empty($filterValue) ) ? true : false;
$addToList = ( $item[$filterBy] == $displayLang ) ? true : false;
if ($key >= $offset && $idx < $limit)
{
$fields['_alt'] = $idx % 2;
$idx++;
$fields['_first'] = $idx == 1 ? true:'';
$fields['_last'] = $idx == $limit ? true:'';
$fields['idx'] = $idx;
$chunk = $modx->newObject('modChunk');
$chunk->setCacheable(false);
$chunk->setContent($template);
$output .= $chunk->process($fields);
}
}
}
}
}
}
$modx->setPlaceholder($totalVar, count($items));
return $output;
The next snippet, "getLanguageItem", uses a MIGx TV called "t_metaContent" that has fields named exactly as the common fields e.g. content, pagetitle, longtitle etc an example of the "Input Options" for "Form Tabs" below:
[
{"caption":"Meta Data", "fields":
[
{"field":"code","caption":"Select the language:","inputTV":"t_code"},
{"field":"pagetitle","caption":"Title:","description":"The translated title of the page"},
{"field":"longtitle","caption":"Long Title:","description":"The translated long title of the page"},
{"field":"content","caption":"Main Content:","inputTV":"t_content"}
]
}
]
The "t_metaContent" looks like the below:
The "getLanguageItem" snippet does use 2 non MODx sessions called "session_lang_display_setting" and "session_site_lang_context" to determine the context and the required language, and brings back the content of the field based on the language code:
<?php
// [[!getLanguageItem? &tvname=`t_metaContent` &field=`pagetitle` &docid=`[[+id]]` ]]
$tvname = $modx->getOption('tvname', $scriptProperties,'');
$docid = $modx->getOption('docid', $scriptProperties,$modx->resource->get('id'));
$field = $modx->getOption('field', $scriptProperties,'');
$processTvs = $modx->getOption('processTvs', $scriptProperties, '');
$tCode = $modx->getOption('tCode', $scriptProperties, 'code'); // Translation field by default it is called code
$justUseDataFromTv = $modx->getOption('justUseDataFromTv', $scriptProperties, ''); //
$debug = $modx->getOption('debug', $scriptProperties, '');
$output = "";
$hasTCode = false;
$isSymlink = false;
if(empty($field)) return;
// Check to see if there is the possibilty of content being translated
$showTranslation = ( isset($_SESSION['session_lang_display_setting']) && $_SESSION['session_lang_display_setting'] != 'en' && $_SESSION['session_site_lang_context'] != 'web' ) ? true : false;
// Get the Session language to display (default is en)
$displayLang = (isset($_SESSION['session_lang_display_setting']) ) ? $_SESSION['session_lang_display_setting'] : 'en';
try
{
// Get the resources for the page
$resource = $modx->getObject('modResource', $docid);
// If we need to check meta content and other TV's, else don't bother
if(empty($justUseDataFromTv))
{
// Check and see if we are dealing with a symlink
if(is_numeric($resource->get('content'))) $isSymlink = true;
// If the translation field is NOT a template variable check that the language IS English
if(empty($processTvs))
{
if($isSymlink)
{
$symlinkId = $modx->runSnippet('getSymlinkId', array('pageid'=>$docid));
// Got to Catch whether the SymlinkId is the same the document ID: would be bad form from the inputter
if($symlinkId == $docid) return 'ERROR: Symlinking to itself. Check Symlink ID in the resource.';
$resource = $modx->getObject('modResource', $symlinkId);
// Got to check whether the resource coming back is a symlink: again Bad form!!!
if($resource->get('class_key') == 'modSymLink') return 'ERROR: Symlinking to a Symlink Resource. Check Symlink ID in the resource';
}
$output = $resource->get($field);
}
else
{
// check to see if there is a TV by the name of the required field
$tv = $modx->getObject('modTemplateVar', array('name' => $field));
if($tv != null)
{
$output = $tv->renderOutput($docid);
}
}
// No need to go further if there is no translation checking to be done.
if(!$showTranslation) return $output;
}
// OK standard fields don't apply from now on.
if(!empty($tvname))
{
if($tv = $modx->getObject('modTemplateVar', array('name' => $tvname)))
{
$outputvalue = $tv->renderOutput($docid);
$properties = $tv->get('input_properties');
$properties = isset($properties['columns']) ? $properties : $tv->getProperties();
$formtabs = $modx->fromJSON($properties['formtabs']);
$inputTvs = array();
$inputFields = array();
if (is_array($formtabs))
{
foreach ($formtabs as $tab)
{
if (isset($tab['fields']))
{
foreach ($tab['fields'] as $f)
{
$inputFields[$f['field']] = $f['field'];
if (isset($f['inputTV']))
{
$inputTvs[$f['field']] = $f['inputTV'];
}
}
}
}
}
}
}
if(empty($outputvalue)) return $output;
// There is an output value to work with.
$items = $modx->fromJSON($outputvalue);
// Next thing to check is whether there is a language code field to check against
if(array_key_exists($tCode,$inputFields))
{
// Create a language array with the items array
$translationArray = array();
foreach($items as $item)
{
if(count($item) > 0)
{
foreach($item as $f => $value)
{
if (isset($inputTvs[$f]))
{
if ($tv = $modx->getObject('modTemplateVar', array('name' => $inputTvs[$f])))
{
$tv->set('default_text', $value);
$translationArray[$item[$tCode]][$f] = $tv->renderOutput($docid);
}
}
else
{
$translationArray[$item[$tCode]][$f] = $value;
}
}
}
}
if(!empty($debug)) var_dump($translationArray);
if(count($translationArray) > 0)
{
$transOutput = $translationArray[$displayLang][$field];
if(!empty($transOutput))
{
$output = $transOutput;
}
}
}
}catch (Exception $e) {
$output = $e->getMessage();
}
return $output;
There is another snippet used in the "getLanguageItem" snippet called "getSymlinkId" which has the following code
<?php
if(empty($pageid))
{
$id = $modx->resource->get('id');
}
else
{
$id = $pageid;
}
$c = $modx->newQuery('modResource');
$c->select('content');
$c->where(array('id'=>$id));
$c->prepare();
$c->stmt->execute();
$symlinkId = $c->stmt->fetchColumn();
$c->stmt->closeCursor();
if(is_numeric($symlinkId) && !empty($symlinkId))
{
return intval($symlinkId);
}
Hopefully these 3 snippets based on MIGx are useful.
Again brilliant work on MIGx Bruno.