MODx multiple language site with template chunks


After using the stuff in the prior tutorial on the site I’m working on at the moment I quickly realized that I needed to be able to use chunks as templates, just like Ditto, to handle repetitive stuff. It doesn’t make sense having duplicate HTML all over the place.

In order to make this happen some changes to the translate snippet needed to be made, let’s start with the listing. I’ll explain how the new stuff works and how to use it below. In the listing code that hasn’t been changed from last time is just abbreviated with .

...
}else{
	if(empty($tpl)){
		foreach($GLOBALS['cur_articles'] as $a){
			if($a['alias'] == $article)
				return $a[$field];
		}
	}else{
		$chunk = $modx->getChunk($tpl);
		foreach($GLOBALS['cur_articles'] as $a){
			if($a['alias'] == $article)
				$ca = $a;
		}
		
		foreach($ca as $key => $value){
		  $patterns[] = "/\[-$key-\]/";
		  $replacements[] = $value;
		}
		
		return preg_replace($patterns, $replacements, $chunk);
	}
}

What we do here is implementing two modes for calling the snippet, do we have a tpl call or not? If not then we use the snippet in exactly the same way as described in the prior article.

If we however do pass a template name we will first retrieve the chunk HTML from the database and then loop through the articles to find one with a matching alias (so calling it this way requires both an alias and chunk name (tpl)). When we have the article we will create two arrays for use with preg_replace, basically all instances of [-*-] will be replaced if they occur in both the chunk and the article, the two most common ones will probably be [-pagetitle-] and [-content-].

A chunk (called test) we want to use as a template might look like this:

<div id="testchunk">
<b>[-pagetitle-]</b>
</div>
[-content-]

Below I’m calling it in another chunk:

[[translate? &article=`e-commerce` &tpl=`test`]]

So the alias of the article, whose pagetitle and content values we want to replace the placeholders in the testchunk with, is e-commerce. Neat :)

Update: We now do template variables too, let’s start with the listing:

...
}else{
	$chunk = $modx->getChunk($tpl);
	foreach($GLOBALS['cur_articles'] as $a){
		if($a['alias'] == $article)
			$ca = $a;
	}
	
	$query = "SELECT DISTINCT tv.name, cv.value FROM ".$modx->getFullTableName('site_tmplvar_contentvalues')." cv, ".
	$modx->getFullTableName('site_tmplvars')." tv WHERE cv.contentid = {$ca['id']} AND cv.tmplvarid = tv.id";
	
	foreach($modx->db->makeArray( $modx->db->query($query)) as $tplvar)
		$ca[ $tplvar['name'] ] = $tplvar['value'];
	
	foreach($ca as $key => $value){
	  $patterns[] = "/\[-$key-\]/";
	  $replacements[] = $value;
	}
	
	return preg_replace($patterns, $replacements, $chunk);
}

So we get all template variables applicable for the current article (in this case it has alias e-commerce), we then loop through our joined table and get the temlate name as key and value as value in the current article. Now it really goes without saying that even if you can you shouldn’t go name a template variable ‘pagetitle’ or ‘content’ here since you will then overwrite default variables.

The chunk can now look like this:

<div id="headline_bkg1">
  <h3>[-pagetitle-]</h3>
</div>
<img class="float_right" src="[(site_url)][-project-image-]" />
<div id="fullwidth_content">
[-content-]
</div>

In this case project-image is the template variable of type image. And at this point I think I’m satisfied for the current project, great.

Related Posts

Tags: , ,