diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php
index 8fe1db462..93443e1e4 100755
--- a/classes/controller/FrontController.php
+++ b/classes/controller/FrontController.php
@@ -536,11 +536,12 @@ class FrontControllerCore extends Controller
if ($this->context->getMobileDevice() == false && Tools::isSubmit('live_edit'))
$this->context->smarty->assign('live_edit', $this->getLiveEditFooter());
- // handle 1.4 theme (with layout.tpl missing)
- if ($this->context->getMobileDevice() != false || file_exists(_PS_THEME_DIR_.'layout.tpl'))
+
+ $layout = $this->getLayout();
+ if ($layout)
{
if ($this->template)
- $this->context->smarty->assign('template', $this->context->smarty->fetch($this->template));
+ $this->context->smarty->display($layout);
else // For retrocompatibility with 1.4 controller
{
ob_start();
@@ -980,14 +981,73 @@ class FrontControllerCore extends Controller
* This is overrided to manage is behaviour
* if a customer access to the site with mobile device.
*/
- public function setTemplate($template)
+ public function setTemplate($default_template)
{
if ($this->context->getMobileDevice() != false)
- $this->setMobileTemplate($template);
+ $this->setMobileTemplate($default_template);
else
- parent::setTemplate($template);
+ {
+ $template = $this->getOverrideTemplate();
+
+ if ($template)
+ parent::setTemplate($template);
+ else
+ parent::setTemplate($default_template);
+ }
}
+ /**
+ * Returns the template corresponding to the current page.
+ * By default this method return false but could easily be overridden in a specific controller
+ *
+ * @since 1.5
+ * @return bool
+ */
+ public function getOverrideTemplate()
+ {
+ return false;
+ }
+
+ /**
+ * Returns the layout corresponding to the current page by using the override system
+ * Ex:
+ * On the url: http://localhost/index.php?id_product=1&controller=product, this method will
+ * check if the layout exists in the following files (in that order), and return the first found:
+ * - /themes/default/override/layout-product-1.tpl
+ * - /themes/default/override/layout-product.tpl
+ * - /themes/default/layout.tpl
+ *
+ * @since 1.5
+ * @return bool|string
+ */
+ public function getLayout()
+ {
+ $entity = Tools::getValue('controller');
+ $id_item = (int)Tools::getValue('id_'.$entity);
+
+ $layout_dir = _PS_THEME_DIR_;
+ $layout_override_dir = _PS_THEME_OVERRIDE_DIR_;
+ if ($this->context->getMobileDevice() != false)
+ {
+ $layout_dir = _PS_THEME_MOBILE_DIR_;
+ $layout_override_dir = _PS_THEME_MOBILE_OVERRIDE_DIR_;
+ }
+
+ $layout = false;
+ if ($entity)
+ {
+ if ($id_item > 0 && file_exists($layout_override_dir.'layout-'.$entity.'-'.$id_item.'.tpl'))
+ $layout = $layout_override_dir.'layout-'.$entity.'-'.$id_item.'.tpl';
+ elseif (file_exists($layout_override_dir.'layout-'.$entity.'.tpl'))
+ $layout = $layout_override_dir.'layout-'.$entity.'.tpl';
+ }
+
+ if (!$layout && file_exists($layout_dir.'layout.tpl'))
+ $layout = $layout_dir.'layout.tpl';
+
+ return $layout;
+ }
+
/**
* This checks if the template set is available for mobile themes,
* otherwise the front template is choosen.
diff --git a/config/defines_uri.inc.php b/config/defines_uri.inc.php
index baa5950e6..bc408a787 100644
--- a/config/defines_uri.inc.php
+++ b/config/defines_uri.inc.php
@@ -32,12 +32,14 @@ define('_THEME_DIR_', _THEMES_DIR_._THEME_NAME_.'/');
define('_THEME_IMG_DIR_', _THEME_DIR_.'img/');
define('_THEME_CSS_DIR_', _THEME_DIR_.'css/');
define('_THEME_JS_DIR_', _THEME_DIR_.'js/');
+define('_THEME_OVERRIDE_DIR_', _PS_THEME_DIR_.'override/');
/* For mobile devices */
if (file_exists(_PS_THEME_DIR_.'mobile/'))
{
define('_PS_THEME_MOBILE_DIR_', _PS_THEME_DIR_.'mobile/');
define('_THEME_MOBILE_DIR_', _THEMES_DIR_._THEME_NAME_.'/mobile/');
+ define('_THEME_MOBILE_OVERRIDE_DIR_', _PS_THEME_MOBILE_DIR_.'override/');
}
else
{
diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php
index a6f3c3f63..c1a4da041 100644
--- a/controllers/admin/AdminTranslationsController.php
+++ b/controllers/admin/AdminTranslationsController.php
@@ -929,55 +929,67 @@ class AdminTranslationsControllerCore extends AdminController
{
$missing_translations_front = array();
$_LANG = $this->fileExists(_PS_THEME_DIR_.'lang', Tools::strtolower($lang).'.php', '_LANG');
- $str_output = '';
/* List templates to parse */
- $templates = array_merge(scandir(_PS_THEME_DIR_), scandir(_PS_ALL_THEMES_DIR_));
+ $templates_per_directory = array(
+ _PS_THEME_DIR_ => scandir(_PS_THEME_DIR_),
+ _PS_THEME_OVERRIDE_DIR_ => scandir(_PS_THEME_OVERRIDE_DIR_),
+ _PS_ALL_THEMES_DIR_ => scandir(_PS_ALL_THEMES_DIR_)
+ );
$count = 0;
$tabs_array = array();
- foreach ($templates as $template)
- if (preg_match('/^(.*).tpl$/', $template) && (file_exists($tpl = _PS_THEME_DIR_.$template) || file_exists($tpl = _PS_ALL_THEMES_DIR_.$template)))
+ foreach ($templates_per_directory as $template_dir => $templates)
+ {
+ $prefix = '';
+ if ($template_dir == _THEME_OVERRIDE_DIR_)
+ $prefix = 'override_';
+
+ foreach ($templates as $template)
{
- $prefix_key = substr(basename($template), 0, -4);
- $new_lang = array();
- $fd = fopen($tpl, 'r');
- $content = fread($fd, filesize($tpl));
-
- /* Search language tags (eg {l s='to translate'}) */
- $regex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( sprintf=.*)?( js=1)?\}/U';
- preg_match_all($regex, $content, $matches);
-
- /* Get string translation */
- foreach ($matches[1] as $key)
+ if (preg_match('/^(.*).tpl$/', $template) && (file_exists($tpl = $template_dir.$template)))
{
- if (empty($key))
+ $prefix_key = $prefix.substr(basename($template), 0, -4);
+ $new_lang = array();
+ $fd = fopen($tpl, 'r');
+ $content = fread($fd, filesize($tpl));
+
+ /* Search language tags (eg {l s='to translate'}) */
+ $regex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( js=1)?\}/U';
+ preg_match_all($regex, $content, $matches);
+
+ /* Get string translation */
+ foreach ($matches[1] as $key)
{
- $this->errors[] = $this->l('Empty string found, please edit:').'
'._PS_THEME_DIR_.''.$template;
- $new_lang[$key] = '';
- }
- else
- {
- // Caution ! front has underscore between prefix key and md5, back has not
- if (isset($_LANG[$prefix_key.'_'.md5($key)]))
- // @todo check if stripslashes is needed, it wasn't present in 1.4
- $new_lang[$key] = stripslashes(html_entity_decode($_LANG[$prefix_key.'_'.md5($key)], ENT_COMPAT, 'UTF-8'));
+ if (empty($key))
+ {
+ $this->errors[] = $this->l('Empty string found, please edit:').'
'.$template_dir.''.$template;
+ $new_lang[$key] = '';
+ }
else
{
- if (!isset($new_lang[$key]))
+ // Caution ! front has underscore between prefix key and md5, back has not
+ if (isset($_LANG[$prefix_key.'_'.md5($key)]))
+ // @todo check if stripslashes is needed, it wasn't present in 1.4
+ $new_lang[$key] = stripslashes(html_entity_decode($_LANG[$prefix_key.'_'.md5($key)], ENT_COMPAT, 'UTF-8'));
+ else
{
- $new_lang[$key] = '';
- if (!isset($missing_translations_front[$prefix_key]))
- $missing_translations_front[$prefix_key] = 1;
- else
- $missing_translations_front[$prefix_key]++;
+ if (!isset($new_lang[$key]))
+ {
+ $new_lang[$key] = '';
+ if (!isset($missing_translations_front[$prefix_key]))
+ $missing_translations_front[$prefix_key] = 1;
+ else
+ $missing_translations_front[$prefix_key]++;
+ }
}
}
}
- }
- $tabs_array[$prefix_key] = $new_lang;
- $count += count($new_lang);
+ $tabs_array[$prefix_key] = $new_lang;
+ $count += count($new_lang);
+ }
}
+ }
$this->tpl_view_vars = array(
'lang' => Tools::strtoupper($lang),