Skip to content

Make a translatable admin

Johan Dufau edited this page Sep 5, 2015 · 2 revisions

Create a suitable database structure

There must be two tables:

  • A root table (such as news)
  • A lang table (such as news_lang)

Admin form

  • View

Load admin js

$this->assign('require', 'witycms/admin');

Assign values

$lang_list = WLang::getLangIds();

$default = array(
	'id'            => 0,
	'parent'        => '',
	'image'         => '',
	'created_date'  => '',
	'modified_date' => ''
);
$default_translatable = array(
	'title'            => '',
	'subtitle'         => '',
	'author'           => !empty($_SESSION['firstname']) || !empty($_SESSION['lastname']) ? trim($_SESSION['firstname'].' '.$_SESSION['lastname']) : $_SESSION['nickname'],
	'content'          => '',
	'url'              => '',
	'meta_title'       => '',
	'meta_description' => '',
);

foreach ($default_translatable as $key => $value) {
	foreach ($lang_list as $id_lang) {
		$default[$key.'_'.$id_lang] = $value;
	}
}

$this->assignDefault($default, $model['data']);

Assign JS values

// Auto-translate
$js_values = array();
foreach ($default as $item => $def) {
	$js_values[$item] = isset($model['data'][$item]) ? $model['data'][$item] : $def;
}
$this->assign('js_values', json_encode($js_values));

Adapt HTML form

Append lang tabs at top of the form:

<div id="translatable-tabs"></div>

Add class "translatable" to all translatable inputs

NB: You can add "ckedit" class to a ckeditor field.

Append some JS at the end of the form:

<script type="text/javascript">
	var js_values = {$js_values};
</script>

Treat values in Controller

// Format translatable fields
$translatable_fields = array('title', 'subtitle', 'content', 'author', 'url', 'meta_title', 'meta_description');
$lang_list = WLang::getLangIds();
$default_id = WLang::getDefaultLangId();

foreach ($translatable_fields as $field) {
	foreach ($lang_list as $i => $id_lang) {
		$value = WRequest::get($field.'_'.$id_lang);

		if ($field == 'url') {
			$value = strtolower(WTools::stripAccents($value));
			$value = preg_replace('#[^a-zA-Z0-9\/\._-]+#', '-', $value);
			$value = trim($value, '-');
		}

		if (($value === null || $value === '') && $id_lang != $default_id) {
			// Use the value of the default lang
			$data_translatable[$id_lang][$field] = $data_translatable[$default_id][$field];
		} else {
			$data_translatable[$id_lang][$field] = $value;
		}
	}
}

Treat values in Model

// Insert in root table
$prep = $this->db->prepare('
	INSERT INTO page(parent, menu, image)
	VALUES (:parent, :menu, :image)
');
// ...

// Insert in lang tables
$exec = true;
foreach ($data_translatable as $id_lang => $values) {
	$prep = $this->db->prepare('
		INSERT INTO page_lang(id_page, id_lang, title, subtitle, author, content, url, meta_title, meta_description)
		VALUES (:id_page, :id_lang, :title, :subtitle, :author, :content, :url, :meta_title, :meta_description)
	');
	// ...
}