diff --git a/core/lib/Thelia/Command/BaseModuleGenerate.php b/core/lib/Thelia/Command/BaseModuleGenerate.php index 9b4d8de44..06e25a077 100644 --- a/core/lib/Thelia/Command/BaseModuleGenerate.php +++ b/core/lib/Thelia/Command/BaseModuleGenerate.php @@ -12,6 +12,8 @@ namespace Thelia\Command; +use Thelia\Model\Module; + /** * base class for module commands * @@ -36,7 +38,7 @@ abstract class BaseModuleGenerate extends ContainerAwareCommand 'Controller', 'EventListeners', 'I18n', - 'AdminIncludes', + Module::ADMIN_INCLUDES_DIRECTORY_NAME, 'templates', ); diff --git a/core/lib/Thelia/Config/I18n/fr_FR.php b/core/lib/Thelia/Config/I18n/fr_FR.php index ca2741585..f40a228cc 100644 --- a/core/lib/Thelia/Config/I18n/fr_FR.php +++ b/core/lib/Thelia/Config/I18n/fr_FR.php @@ -23,11 +23,11 @@ return array( 'Alpha code 3 *' => 'Code Alpha 3 *', 'Amount removed from the cart' => 'Montant déduit du panier', 'Apply exchange rates on price in %sym' => 'Appliquer le taux de change sur le prix en %sym', - 'Area' => 'Zone', 'Attribute ID:Attribute AV ID' => 'Déclinaison ID : Valeur de déclinaison ID', 'Auth mode' => 'Mode d\'authentification', 'Available quantity' => 'Quantité disponible', 'Available quantity *' => 'Quantité disponible *', + 'Available shipping zones' => 'Zones de livraison disponibles', 'Bad tax list JSON' => 'Mauvais JSON de la liste des taxes', 'Business ID' => 'ID du business', 'Cannot find a default country. Please define one.' => 'Impossible de trouver un pays par défaut. Veuillez en définir un.', @@ -64,6 +64,7 @@ return array( 'Emergency' => 'Urgence', 'Enable remote SMTP use' => 'Activer l\'utilisation d\'un serveur SMTP distant.', 'Encryption' => 'Chiffrement', + 'Error occured while processing order ref. %ref, ID %id: %err' => 'Un erreur est survenue paedant le traitement de la commande ref. %ref, ID %id; %err', 'Errors' => 'Erreurs', 'Failed to update language definition: %ex' => 'Erreur lors de la mise à jour de la définition de la langue : %ex', 'Fax' => 'Fax', @@ -91,6 +92,8 @@ return array( 'Log level *' => 'Niveau de log *', 'Login' => 'Connexion', 'Login failed. Please check your username and password.' => 'Erreur de login. Veuillez vérifier votre login et votre mot de passe.', + 'Loop must implements \'PropelSearchLoopInterface\' to be timestampable' => 'Les classes \'boucle\' doivent implémenter \'PropelSearchLoopInterface\' pour être horodatables', + 'Loop must implements \'PropelSearchLoopInterface\' to be versionable' => 'Les classes \'boucle\' doivent implémenter \'PropelSearchLoopInterface\' pour être versonnables', 'Make this address as my primary address' => 'Choisir cette adresse comme adresse par défaut', 'Message subject' => 'Sujet', 'Meta Description' => 'Meta description', @@ -105,9 +108,13 @@ return array( 'New Password' => 'Nouveau mot de passe.', 'No %obj was created.' => 'aucun %obj n\'a été créé.', 'No %obj was updated.' => 'Aucun %obj mis à jour', + 'No module found for code \'%item\'' => 'Aucun module trouvé pour \'%item\' ', 'No, I am a new customer.' => 'Non, je suis un nouveau client.', + 'Not found' => 'Non trouvé.', 'Notices' => 'Notices', 'Order address ID not found' => 'ID de l\'adresse de la commande non trouvé', + 'Order ref. %ref is now unpaid.' => 'La commande %ref, ID %id est désormais non payée', + 'Order ref. %ref, ID %id has been successfully paid.' => 'La commande ref. %ref, ID %id a été correctement payée', 'Page Title' => 'Titre de la page', 'Parent category *' => 'Catégorie parente *', 'Parent folder *' => 'Dossier parent *', @@ -129,6 +136,8 @@ return array( 'Prevent variable modification or deletion, except for super-admin' => 'Prévenir la suppression ou la modification de variables, excepté pour les super-administrateurs.', 'Price' => 'Prix', 'Price currency *' => 'Devise *', + 'Processing cancelation of payment for order ref. %ref' => 'Traitement de l\'annulation du paiement de la commande %ref, ID %id', + 'Processing confirmation of order ref. %ref, ID %id' => 'Traitement de la confirmation de la commande %ref, ID %id', 'Prodcut ID *' => 'ID du produit *', 'Product ID' => 'ID produit', 'Product ID *' => 'ID produit *', @@ -147,6 +156,7 @@ return array( 'Profile ID not found' => 'ID du profil non trouvé', 'Profile `code` already exists' => 'Le `code` du profil existe déjà', 'Purpose *' => 'Objet', + 'Quantity' => 'Quantité', 'Rate from € *' => 'Taux à partie de l\'€ *', 'Redirecting ...' => 'Redirection ...', 'Redirecting to %url' => 'Redirection vers %url', @@ -162,11 +172,13 @@ return array( 'Rotated Text File' => 'Rotation du fichier texte', 'Sale price excluding taxes' => 'Prix de vente Hors Taxes', 'Sale price including taxes' => 'Prix de vente Toutes Taxes Comprises', + 'Shipping zone name' => 'Nom de la zone de livraison', 'Show redirections *' => 'Montrer les redirections *', 'Sorry, an error occured: %msg' => 'Désolé, une erreur est survenue : %msg', 'Sorry, you are not allowed to perform this action.' => 'Désolé, vous n\'êtes pas autorisé à réaliser cette action.', 'Sorry, you\'re not allowed to perform this action' => 'Désolé, vous n\'êtes pas autorisé à réaliser cette action.', 'Source IP' => 'IP source', + 'Stats on %month/%year' => 'Statisticues pour %month/%year ', 'Store configuration failed.' => 'Erreur de configuration du magasin.', 'Store email address' => 'Adresse mail du magasin', 'Store logs into text file' => 'Conserver les logs dans des fichiers texte', @@ -205,13 +217,18 @@ return array( 'Title *' => 'Titre *', 'Title ID not found' => 'ID de la civilité non trouvé', 'Type' => 'Type', + 'Unavailable' => 'Non disponible.', + 'Undefined loop argument "%name"' => 'Argument de boucle invalide: "%name" ', + 'Undefined search mode \'%mode\'' => 'Mode de recherche \'%mode\' invalide', + 'Undefined translation type: %item' => 'Type de traduction inconnu:%item ', + 'Unknown order ID: %id' => 'La commande ID %id est inconnue.', + 'Unsupported magic method %name. only getArgname() is supported.' => 'La méthode magique %name n\'est pas supportée. Seule get() est supporté..', 'Username' => 'Nom d\'utilisateur', 'Username *' => 'Nom d\'utilisateur *', 'Value' => 'Valeur', 'Value *' => 'Valeur *', 'Warnings' => 'Avertissements', 'Weight' => 'Poids', - 'Weight *' => 'Poids *', 'Yes, I have a password :' => 'Oui, j\'ai un mot de passe :', 'You are already registered!' => 'Vous êtes déjà enregistré !', 'Your Email Address' => 'Votre adresse mail', @@ -226,7 +243,6 @@ return array( 'password must be composed of at least 4 characters' => 'le mot de passe doit être composé d\'au moins 4 caractères', 'payment module %s is not a Thelia\Module\PaymentModuleInterface' => 'Le module de paiement %s n\'est pas une instance de Thelia\Module\PaymentModuleInterface ', 'quantity value is not valid' => 'la valeur de la quantité n\'est pas valide', - 'shipping area name' => 'Nom de la zone de livraison', 'this product id does not exists : %d' => 'l\'id du produit %d n\'existe pas', 'time format' => 'Format d\'heure', ); diff --git a/core/lib/Thelia/Controller/Admin/TranslationsController.php b/core/lib/Thelia/Controller/Admin/TranslationsController.php index 59a26dc1c..b8cffdcd0 100644 --- a/core/lib/Thelia/Controller/Admin/TranslationsController.php +++ b/core/lib/Thelia/Controller/Admin/TranslationsController.php @@ -14,6 +14,7 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Security\AccessManager; +use Thelia\Model\Module; use Thelia\Model\ModuleQuery; use Thelia\Core\Template\TemplateHelper; use Thelia\Core\Template\TemplateDefinition; @@ -25,13 +26,45 @@ use Thelia\Tools\URL; */ class TranslationsController extends BaseAdminController { + /** + * @param string $item_name the modume code + * @return Module the module object + * @throws \InvalidArgumentException if module was not found + */ + protected function getModule($item_name) { + if (null !== $module = ModuleQuery::create()->findPk($item_name)) + return $module; + + throw new \InvalidArgumentException( + $this->getTranslator()->trans("No module found for code '%item'", ['%item' => $item_name]) + ); + } + + protected function getModuleTemplateNames(Module $module, $template_type) { + $templates = + TemplateHelper::getInstance()->getList( + $template_type, + $module->getAbsoluteTemplateBasePath() + ); + + $names = []; + + foreach($templates as $template) $names[] = $template->getName(); + + return $names; + } + protected function renderTemplate() { - // Get related strings, if all input data are here $item_to_translate = $this->getRequest()->get('item_to_translate'); - $item_id = $this->getRequest()->get('item_id', ''); + $item_name = $this->getRequest()->get('item_name', ''); + + if ($item_to_translate == 'mo' && ! empty($item_name)) + $module_part = $this->getRequest()->get('module_part', ''); + else + $module_part = false; $all_strings = array(); @@ -41,51 +74,106 @@ class TranslationsController extends BaseAdminController $templateArguments = array( 'item_to_translate' => $item_to_translate, - 'item_id' => $item_id, + 'item_name' => $item_name, + 'module_part' => $module_part, 'view_missing_traductions_only' => $this->getRequest()->get('view_missing_traductions_only', 0), 'max_input_vars_warning' => false, ); // Find the i18n directory, and the directory to examine. - if (! empty($item_id) || $item_to_translate == 'co') { + if (! empty($item_name) || $item_to_translate == 'co') { switch ($item_to_translate) { + // Module core case 'mo' : - if (null !== $module = ModuleQuery::create()->findPk($item_id)) { + $module = $this->getModule($item_name); + + if ($module_part == 'core') { $directory = $module->getAbsoluteBaseDir(); + $domain = $module->getTranslationDomain(); $i18n_directory = $module->getAbsoluteI18nPath(); $walkMode = TemplateHelper::WALK_MODE_PHP; } + else if ($module_part == 'admin-includes') { + $directory = $module->getAbsoluteAdminIncludesPath(); + $domain = $module->getAdminIncludesTranslationDomain(); + $i18n_directory = $module->getAbsoluteAdminIncludesI18nPath(); + $walkMode = TemplateHelper::WALK_MODE_TEMPLATE; + } + else if (! empty($module_part)) { + // Front or back office template, form of $module_part is [bo|fo].subdir-name + list($type, $subdir) = explode('.', $module_part); + + if ($type == 'bo') { + $directory = $module->getAbsoluteBackOfficeTemplatePath($subdir); + $domain = $module->getBackOfficeTemplateTranslationDomain($subdir); + $i18n_directory = $module->getAbsoluteBackOfficeI18nTemplatePath($subdir); + } + else if ($type == 'fo') { + $directory = $module->getAbsoluteFrontOfficeTemplatePath($subdir); + $domain = $module->getFrontOfficeTemplateTranslationDomain($subdir); + $i18n_directory = $module->getAbsoluteFrontOfficeI18nTemplatePath($subdir); + } + else { + throw new \InvalidArgumentException("Undefined module template type: '$type'."); + } + $walkMode = TemplateHelper::WALK_MODE_TEMPLATE; + + } + + // List front and back office templates defined by this module + $templateArguments['back_office_templates'] = + $this->getModuleTemplateNames($module, TemplateDefinition::BACK_OFFICE); + + $templateArguments['front_office_templates'] = + $this->getModuleTemplateNames($module, TemplateDefinition::FRONT_OFFICE); + break; + // Thelia Core case 'co' : $directory = THELIA_ROOT . 'core/lib/Thelia'; + $domain = 'core'; $i18n_directory = THELIA_ROOT . 'core/lib/Thelia/Config/I18n'; $walkMode = TemplateHelper::WALK_MODE_PHP; break; + // Front-office template case 'fo' : - $template = new TemplateDefinition($item_id, TemplateDefinition::FRONT_OFFICE); + $template = new TemplateDefinition($item_name, TemplateDefinition::FRONT_OFFICE); break; + // Back-office template case 'bo' : - $template = new TemplateDefinition($item_id, TemplateDefinition::BACK_OFFICE); + $template = new TemplateDefinition($item_name, TemplateDefinition::BACK_OFFICE); break; + // PDF templates case 'pf' : - $template = new TemplateDefinition($item_id, TemplateDefinition::PDF); + $template = new TemplateDefinition($item_name, TemplateDefinition::PDF); break; + // Email templates case 'ma' : - $template = new TemplateDefinition($item_id, TemplateDefinition::EMAIL); + $template = new TemplateDefinition($item_name, TemplateDefinition::EMAIL); break; + + default: + /* + throw new \InvalidArgumentException( + $this->getTranslator()->trans("Undefined translation type: %item", ['%item' => $item_to_translate]) + ); + */ } if ($template) { $directory = $template->getAbsolutePath(); + $i18n_directory = $template->getAbsoluteI18nPath(); + + $domain = $template->getTranslationDomain(); } // Load strings to translate @@ -102,11 +190,11 @@ class TranslationsController extends BaseAdminController if (! empty($texts)) { - $file = sprintf("%s/%s.php", $i18n_directory, $this->getCurrentEditionLocale()); + $file = sprintf("%s".DS."%s.php", $i18n_directory, $this->getCurrentEditionLocale()); $translations = $this->getRequest()->get('translation', array()); - TemplateHelper::getInstance()->writeTranslation($file, $texts, $translations); + TemplateHelper::getInstance()->writeTranslation($file, $texts, $translations, true); if ($save_mode == 'stay') $this->redirectToRoute("admin.configuration.translations", $templateArguments); @@ -122,6 +210,7 @@ class TranslationsController extends BaseAdminController $walkMode, $this->getTranslator(), $this->getCurrentEditionLocale(), + $domain, $all_strings ); diff --git a/core/lib/Thelia/Core/Template/Loop/Module.php b/core/lib/Thelia/Core/Template/Loop/Module.php index b109a238d..fe61cc8d2 100644 --- a/core/lib/Thelia/Core/Template/Loop/Module.php +++ b/core/lib/Thelia/Core/Template/Loop/Module.php @@ -166,6 +166,7 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface public function parseResults(LoopResult $loopResult) { + /** @var \Thelia\Model\Module $module */ foreach ($loopResult->getResultDataCollection() as $module) { $loopResultRow = new LoopResultRow($module); $loopResultRow->set("ID", $module->getId()) @@ -199,13 +200,13 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface /* if not ; test if it uses admin inclusion : module_configuration.html */ if (false === $hasConfigurationInterface) { - if (file_exists( sprintf("%s/AdminIncludes/%s.html", $module->getAbsoluteBaseDir(), "module_configuration"))) { + if (file_exists($module->getAbsoluteAdminIncludesPath() . DS . "module_configuration.html")) { $hasConfigurationInterface = true; } } } else { // Make a quick and dirty test on the module's routing.xml file - $routing = @file_get_contents($module->getAbsoluteBaseDir() . DS . "Config" . DS . "routing.xml"); + $routing = @file_get_contents($module->getAbsoluteConfigPath() . DS . "routing.xml"); if ($routing && strpos($routing, '/admin/module/') !== false) { $hasConfigurationInterface = true; diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php index 1dbde4cc8..47fb45d8d 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php @@ -80,8 +80,8 @@ class AdminUtilities extends AbstractSmartyPlugin */ - if ($permissions == null || $this->securityContext->isGranted( - "ADMIN", + if ($this->securityContext->isGranted( + array("ADMIN"), $resource === null ? array() : array($resource), $module === null ? array() : array($module), array($access)) diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index 4d5f93536..c067e32a1 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -63,13 +63,14 @@ class Module extends AbstractSmartyPlugin $modules = ModuleQuery::getActivated(); + /** @var \Thelia\Model\Module $module */ foreach ($modules as $module) { if (null !== $moduleLimit && $moduleLimit != $module->getCode()) { continue; } - $file = sprintf("%s/AdminIncludes/%s.html", $module->getAbsoluteBaseDir(), $location); + $file = $module->getAbsoluteAdminIncludesPath() . DS . $location . '.html'; if (file_exists($file)) { diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Translation.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Translation.php index 2bf1e5774..79c859dc1 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Translation.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Translation.php @@ -19,41 +19,59 @@ use Symfony\Component\Translation\TranslatorInterface; class Translation extends AbstractSmartyPlugin { protected $translator; + protected $defaultTranslationDomain = ''; public function __construct(TranslatorInterface $translator) { $this->translator = $translator; } + /** + * Set the default translation domain + * + * @param array $params + * @param \Smarty_Internal_Template $smarty + * @return string + */ + public function setDefaultTranslationDomain($params, &$smarty) + { + $this->defaultTranslationDomain = $this->getParam($params, 'domain'); + } + /** * Process translate function * - * @param unknown $params - * @param unknown $smarty + * @param array $params + * @param \Smarty_Internal_Template $smarty * @return string */ public function translate($params, &$smarty) { - // All parameters other than 'l' are supposed to be variables. Build an array of var => value pairs + // All parameters other than 'l' and 'd' are supposed to be variables. Build an array of var => value pairs // and pass it to the translator $vars = array(); foreach ($params as $name => $value) { - if ($name != 'l') $vars["%$name"] = $value; + if ($name != 'l' && $name != 'd') $vars["%$name"] = $value; } - return $this->translator->trans($this->getParam($params, 'l'), $vars); - } + return $this->translator->trans( + $this->getParam($params, 'l'), + $vars, + $this->getParam($params, 'd', $this->defaultTranslationDomain) + ); +} /** - * Define the various smarty plugins hendled by this class + * Define the various smarty plugins handled by this class * - * @return an array of smarty plugin descriptors + * @return SmartyPluginDescriptor[] an array of smarty plugin descriptors */ public function getPluginDescriptors() { return array( new SmartyPluginDescriptor('function', 'intl', $this, 'translate'), + new SmartyPluginDescriptor('function', 'default_translation_domain', $this, 'setDefaultTranslationDomain'), ); } } diff --git a/core/lib/Thelia/Core/Template/TemplateDefinition.php b/core/lib/Thelia/Core/Template/TemplateDefinition.php index e7387cea5..5d1210134 100644 --- a/core/lib/Thelia/Core/Template/TemplateDefinition.php +++ b/core/lib/Thelia/Core/Template/TemplateDefinition.php @@ -46,6 +46,8 @@ class TemplateDefinition */ protected $type; + protected $translationDomainPrefix; + public function __construct($name, $type) { $this->name = $name; @@ -54,22 +56,31 @@ class TemplateDefinition switch ($type) { case TemplateDefinition::FRONT_OFFICE: $this->path = self::FRONT_OFFICE_SUBDIR . DS . $name; + $this->translationDomainPrefix = 'fo.'; break; case TemplateDefinition::BACK_OFFICE: $this->path = self::BACK_OFFICE_SUBDIR . DS . $name; + $this->translationDomainPrefix = 'bo.'; break; case TemplateDefinition::PDF: $this->path = self::PDF_SUBDIR . DS . $name; + $this->translationDomainPrefix = 'pdf.'; break; case TemplateDefinition::EMAIL: $this->path = self::EMAIL_SUBDIR . DS . $name; + $this->translationDomainPrefix = 'email.'; break; default: $this->path = $name; + $this->translationDomainPrefix = 'generic.'; break; } } + public function getTranslationDomain() { + return $this->translationDomainPrefix . strtolower($this->getName()); + } + public function getName() { return $this->name; diff --git a/core/lib/Thelia/Core/Template/TemplateHelper.php b/core/lib/Thelia/Core/Template/TemplateHelper.php index d2068ce3b..ae0ff27c1 100644 --- a/core/lib/Thelia/Core/Template/TemplateHelper.php +++ b/core/lib/Thelia/Core/Template/TemplateHelper.php @@ -12,6 +12,7 @@ namespace Thelia\Core\Template; +use Symfony\Component\Filesystem\Filesystem; use Thelia\Model\ConfigQuery; use Thelia\Log\Tlog; use Thelia\Core\Translation\Translator; @@ -96,9 +97,10 @@ class TemplateHelper * Return a list of existing templates for a given template type * * @param int $templateType the template type - * @return An array of \Thelia\Core\Template\TemplateDefinition + * @param string the template base (module or core, default to core). + * @return TemplateDefinition[] of \Thelia\Core\Template\TemplateDefinition */ - public function getList($templateType) + public function getList($templateType, $base = THELIA_TEMPLATE_DIR) { $list = $exclude = array(); @@ -108,24 +110,29 @@ class TemplateHelper if ($templateType == $type) { - $baseDir = THELIA_TEMPLATE_DIR.$subdir; + $baseDir = rtrim($base, DS).DS.$subdir; - // Every subdir of the basedir is supposed to be a template. - $di = new \DirectoryIterator($baseDir); + try { + // Every subdir of the basedir is supposed to be a template. + $di = new \DirectoryIterator($baseDir); - foreach ($di as $file) { - // Ignore 'dot' elements - if ($file->isDot() || ! $file->isDir()) continue; + foreach ($di as $file) { + // Ignore 'dot' elements + if ($file->isDot() || ! $file->isDir()) continue; - // Ignore reserved directory names - if (in_array($file->getFilename(), $exclude)) continue; + // Ignore reserved directory names + if (in_array($file->getFilename(), $exclude)) continue; - $list[] = new TemplateDefinition($file->getFilename(), $templateType); + $list[] = new TemplateDefinition($file->getFilename(), $templateType); + } + } + catch (\UnexpectedValueException $ex) { + // Ignore the exception and continue } - - return $list; } } + + return $list; } protected function normalizePath($path) @@ -152,11 +159,12 @@ class TemplateHelper * @param string $walkMode type of file scanning: WALK_MODE_PHP or WALK_MODE_TEMPLATE * @param \Thelia\Core\Translation\Translator $translator the current translator * @param string $currentLocale the current locale + * @param string $domain the translation domain (fontoffice, backoffice, module, etc...) * @param array $strings the list of strings * @throws \InvalidArgumentException if $walkMode contains an invalid value * @return number the total number of translatable texts */ - public function walkDir($directory, $walkMode, Translator $translator, $currentLocale, &$strings) + public function walkDir($directory, $walkMode, Translator $translator, $currentLocale, $domain, &$strings) { $num_texts = 0; @@ -165,7 +173,7 @@ class TemplateHelper $allowed_exts = array('php'); } elseif ($walkMode == self::WALK_MODE_TEMPLATE) { - $prefix = '\{intl[\s]l='; + $prefix = "\\{intl(?:.*?)l="; $allowed_exts = array('html', 'tpl', 'xml'); } else { @@ -178,11 +186,12 @@ class TemplateHelper Tlog::getInstance()->debug("Walking in $directory, in mode $walkMode"); + /** @var \DirectoryIterator $fileInfo */ foreach (new \DirectoryIterator($directory) as $fileInfo) { if ($fileInfo->isDot()) continue; - if ($fileInfo->isDir()) $num_texts += $this->walkDir($fileInfo->getPathName(), $walkMode, $translator, $currentLocale, $strings); + if ($fileInfo->isDir()) $num_texts += $this->walkDir($fileInfo->getPathName(), $walkMode, $translator, $currentLocale, $domain, $strings); if ($fileInfo->isFile()) { @@ -219,7 +228,7 @@ class TemplateHelper $strings[$hash] = array( 'files' => array($short_path), 'text' => $match, - 'translation' => $translator->trans($match, array(), 'messages', $currentLocale, false), + 'translation' => $translator->trans($match, array(), $domain, $currentLocale, false), 'dollar' => strstr($match, '$') !== false ); } @@ -233,13 +242,24 @@ class TemplateHelper return $num_texts; } catch (\UnexpectedValueException $ex) { - echo $ex; + // Directory does not exists => ignore/ } } - public function writeTranslation($file, $texts, $translations) + public function writeTranslation($file, $texts, $translations, $createIfNotExists = false) { + $fs = new Filesystem(); + + if (! $fs->exists($file) && true === $createIfNotExists) { + + $dir = dirname($file); + + if (! $fs->exists($file)) { + $fs->mkdir($dir); + } + } + if ($fp = @fopen($file, 'w')) { fwrite($fp, '<' . "?php\n\n"); diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 1e2921a31..c89e54084 100644 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -34,6 +34,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Thelia\Core\Event\TheliaEvents; use Thelia\Config\DatabaseConfiguration; use Thelia\Config\DefinePropel; +use Thelia\Core\Template\ParserInterface; use Thelia\Core\Template\TemplateDefinition; use Thelia\Core\DependencyInjection\Loader\XmlFileLoader; @@ -43,6 +44,7 @@ use Propel\Runtime\Propel; use Propel\Runtime\Connection\ConnectionManagerSingle; use Thelia\Core\Template\TemplateHelper; use Thelia\Log\Tlog; +use Thelia\Model\Module; class Thelia extends Kernel { @@ -93,8 +95,8 @@ class Thelia extends Kernel /** * Add all module's standard templates to the parser environment * - * @param TheliaParser $parser the parser - * @param Module $module the Module. + * @param ParserInterface $parser the parser + * @param Module $module the Module. */ protected function addStandardModuleTemplatesToParserEnvironment($parser, $module) { @@ -108,10 +110,10 @@ class Thelia extends Kernel /** * Add a module template directory to the parser environment * - * @param TheliaParser $parser the parser - * @param Module $module the Module. - * @param string $templateType the template type (one of the TemplateDefinition type constants) - * @param string $templateSubdirName the template subdirectory name (one of the TemplateDefinition::XXX_SUBDIR constants) + * @param ParserInterface $parser the parser + * @param Module $module the Module. + * @param string $templateType the template type (one of the TemplateDefinition type constants) + * @param string $templateSubdirName the template subdirectory name (one of the TemplateDefinition::XXX_SUBDIR constants) */ protected function addModuleTemplateToParserEnvironment($parser, $module, $templateType, $templateSubdirName) { @@ -168,8 +170,11 @@ class Thelia extends Kernel $modules = \Thelia\Model\ModuleQuery::getActivated(); $translationDirs = array(); + + /** @var ParserInterface $parser */ $parser = $container->getDefinition('thelia.parser'); + /** @var Module $module */ foreach ($modules as $module) { try { @@ -190,14 +195,21 @@ class Thelia extends Kernel } else { $container->addCompilerPass($compiler); } - } $loader = new XmlFileLoader($container, new FileLocator($module->getAbsoluteConfigPath())); $loader->load("config.xml"); + $moduleDomain = strtolower($module->getCode()); + + // Core module translation if (is_dir($dir = $module->getAbsoluteI18nPath())) { - $translationDirs[] = $dir; + $translationDirs[$module->getTranslationDomain()] = $dir; + } + + // Admin includes translation + if (is_dir($dir = $module->getAbsoluteAdminIncludesI18nPath())) { + $translationDirs[$module->getAdminIncludesTranslationDomain()] = $dir; } $this->addStandardModuleTemplatesToParserEnvironment($parser, $module); @@ -207,16 +219,16 @@ class Thelia extends Kernel } } - // Load translation from templates - // core translation - $translationDirs[] = THELIA_ROOT . "core/lib/Thelia/Config/I18n"; + // Load core translation + $translationDirs['core'] = THELIA_ROOT . "core/lib/Thelia/Config/I18n"; // Standard templates (front, back, pdf, mail) $th = TemplateHelper::getInstance(); + /** @var TemplateDefinition $templateDefinition */ foreach ($th->getStandardTemplateDefinitions() as $templateDefinition) { if (is_dir($dir = $templateDefinition->getAbsoluteI18nPath())) { - $translationDirs[] = $dir; + $translationDirs[$templateDefinition->getTranslationDomain()] = $dir; } } @@ -230,14 +242,19 @@ class Thelia extends Kernel { $translator = $container->getDefinition('thelia.translator'); - $finder = Finder::create() - ->files() - ->depth(0) - ->in($dirs); + foreach ($dirs as $domain => $dir) { - foreach ($finder as $file) { - list($locale, $format) = explode('.', $file->getBaseName(), 2); - $translator->addMethodCall('addResource', array($format, (string) $file, $locale)); + $finder = Finder::create() + ->files() + ->depth(0) + ->in($dir); + + /** @var \DirectoryIterator $file */ + foreach ($finder as $file) { + list($locale, $format) = explode('.', $file->getBaseName(), 2); + + $translator->addMethodCall('addResource', array($format, (string) $file, $locale, $domain)); + } } } diff --git a/core/lib/Thelia/Core/Translation/Translator.php b/core/lib/Thelia/Core/Translation/Translator.php index 756bb5973..b3db0e73c 100644 --- a/core/lib/Thelia/Core/Translation/Translator.php +++ b/core/lib/Thelia/Core/Translation/Translator.php @@ -14,6 +14,7 @@ namespace Thelia\Core\Translation; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Translation\Translator as BaseTranslator; +use Thelia\Log\Tlog; class Translator extends BaseTranslator { @@ -63,7 +64,7 @@ class Translator extends BaseTranslator * * @api */ - public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null, $return_default_if_not_available = true) + public function trans($id, array $parameters = array(), $domain = 'core', $locale = null, $return_default_if_not_available = true) { if (null === $locale) { $locale = $this->getLocale(); @@ -73,11 +74,19 @@ class Translator extends BaseTranslator $this->loadCatalogue($locale); } - if ($this->catalogues[$locale]->has((string) $id, $domain)) + if (! $this->catalogues[$locale]->has((string) $id, $domain)) { + + } + + if ($this->catalogues[$locale]->has((string) $id, $domain)) { return parent::trans($id, $parameters, $domain, $locale); - else if ($return_default_if_not_available) - return strtr($id, $parameters); - else - return ''; + } else { + Tlog::getInstance()->addWarning("Undefined translation: locale: $locale, domain: $domain, ID: $id"); + + if ($return_default_if_not_available) + return strtr($id, $parameters); + else + return ''; + } } } diff --git a/core/lib/Thelia/Model/Module.php b/core/lib/Thelia/Model/Module.php index 65ea065d9..72149665e 100644 --- a/core/lib/Thelia/Model/Module.php +++ b/core/lib/Thelia/Model/Module.php @@ -1,95 +1,179 @@ -getCode()); - } - - /** - * @return the module's base directory path, relative to THELIA_MODULE_DIR - */ - public function getAbsoluteBaseDir() - { - return THELIA_MODULE_DIR . $this->getBaseDir(); - } - - /** - * @return the module's config directory path, relative to THELIA_MODULE_DIR - */ - public function getConfigPath() - { - return $this->getBaseDir() . DS . "Config"; - } - - /** - * @return the module's config absolute directory path - */ - public function getAbsoluteConfigPath() - { - return THELIA_MODULE_DIR . $this->getConfigPath(); - } - - /** - * @return the module's i18N directory path, relative to THELIA_MODULE_DIR - */ - public function getI18nPath() - { - return $this->getBaseDir() . DS . "I18n"; - } - - /** - * @return the module's i18N absolute directory path - */ - public function getAbsoluteI18nPath() - { - return THELIA_MODULE_DIR . $this->getI18nPath(); - } - - /** - * Return the absolute path to one of the module's template directories - * - * @param int $templateSubdirName the name of the, probably one of TemplateDefinition::xxx_SUBDIR constants - */ - public function getAbsoluteTemplateDirectoryPath($templateSubdirName) - { - return sprintf("%s%stemplates%s%s", $this->getAbsoluteBaseDir(), DS, DS, $templateSubdirName); - } - - /** - * Calculate next position relative to module type - */ - protected function addCriteriaToPositionQuery($query) - { - $query->filterByType($this->getType()); - } - - /** - * {@inheritDoc} - */ - public function preInsert(ConnectionInterface $con = null) - { - $this->setPosition($this->getNextPosition()); - - return true; - } -} +getCode()); + } + + public function getAdminIncludesTranslationDomain() { + return $this->getTranslationDomain().'.ai'; + } + + public function getAbsoluteBackOfficeTemplatePath($subdir) + { + return sprintf("%s".DS."%s".DS."%s", + $this->getAbsoluteTemplateBasePath(), + TemplateDefinition::BACK_OFFICE_SUBDIR, + $subdir + ); + } + + public function getAbsoluteBackOfficeI18nTemplatePath($subdir) + { + return sprintf("%s".DS."%s".DS."%s", + $this->getAbsoluteI18nPath(), + TemplateDefinition::BACK_OFFICE_SUBDIR, + $subdir + ); + } + + public function getBackOfficeTemplateTranslationDomain($templateName) { + return $this->getTranslationDomain(). '.bo.' . $templateName; + } + + public function getAbsoluteFrontOfficeTemplatePath($subdir) + { + return sprintf("%s".DS."%s".DS."%s", + $this->getAbsoluteTemplateBasePath(), + TemplateDefinition::FRONT_OFFICE_SUBDIR, + $subdir + ); + } + + public function getAbsoluteFrontOfficeI18nTemplatePath($subdir) + { + return sprintf("%s".DS."%s".DS."%s", + $this->getAbsoluteI18nPath(), + TemplateDefinition::FRONT_OFFICE_SUBDIR, + $subdir + ); + } + + public function getFrontOfficeTemplateTranslationDomain($templateName) { + return $this->getTranslationDomain(). '.fo.' . $templateName; + } + + /** + * @return the module's base directory path, relative to THELIA_MODULE_DIR + */ + public function getBaseDir() + { + return ucfirst($this->getCode()); + } + + /** + * @return the module's base directory path, relative to THELIA_MODULE_DIR + */ + public function getAbsoluteBaseDir() + { + return THELIA_MODULE_DIR . $this->getBaseDir(); + } + + /** + * @return the module's config directory path, relative to THELIA_MODULE_DIR + */ + public function getConfigPath() + { + return $this->getBaseDir() . DS . "Config"; + } + + /** + * @return the module's config absolute directory path + */ + public function getAbsoluteConfigPath() + { + return THELIA_MODULE_DIR . $this->getConfigPath(); + } + + /** + * @return the module's i18N directory path, relative to THELIA_MODULE_DIR + */ + public function getI18nPath() + { + return $this->getBaseDir() . DS . "I18n"; + } + + /** + * @return the module's i18N absolute directory path + */ + public function getAbsoluteI18nPath() + { + return THELIA_MODULE_DIR . $this->getI18nPath(); + } + + /** + * @return the module's AdminIncludes absolute directory path + */ + public function getAbsoluteAdminIncludesPath() + { + return $this->getAbsoluteBaseDir() . DS . self::ADMIN_INCLUDES_DIRECTORY_NAME; + } + + /** + * @return the module's AdminIncludes i18N absolute directory path + */ + public function getAbsoluteAdminIncludesI18nPath() + { + return THELIA_MODULE_DIR . $this->getI18nPath() . DS . self::ADMIN_INCLUDES_DIRECTORY_NAME; + } + + /** + * Return the absolute path to the module's template directory + * + * @return string a path + */ + public function getAbsoluteTemplateBasePath() + { + return $this->getAbsoluteBaseDir() . DS . 'templates'; + } + + /** + * Return the absolute path to one of the module's template directories + * + * @param int $templateSubdirName the name of the, probably one of TemplateDefinition::xxx_SUBDIR constants + * @return string a path + */ + public function getAbsoluteTemplateDirectoryPath($templateSubdirName) + { + return $this->getAbsoluteTemplateBasePath() .DS. $templateSubdirName; + } + + /** + * Calculate next position relative to module type + */ + protected function addCriteriaToPositionQuery($query) + { + $query->filterByType($this->getType()); + } + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->setPosition($this->getNextPosition()); + + return true; + } +} diff --git a/templates/backOffice/default/admin-layout.tpl b/templates/backOffice/default/admin-layout.tpl index 42dcaed72..5e9f09cca 100644 --- a/templates/backOffice/default/admin-layout.tpl +++ b/templates/backOffice/default/admin-layout.tpl @@ -10,6 +10,9 @@ {* -- Declare assets directory, relative to template base directory --------- *} {declare_assets directory='assets'} +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'} + diff --git a/templates/backOffice/default/ajax/language-update-modal.html b/templates/backOffice/default/ajax/language-update-modal.html index 82e8d3731..f23e6d552 100644 --- a/templates/backOffice/default/ajax/language-update-modal.html +++ b/templates/backOffice/default/ajax/language-update-modal.html @@ -1,3 +1,6 @@ +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'} + {* Update an Address *} {form name="thelia.lang.update"} diff --git a/templates/backOffice/default/ajax/product-attributes-tab.html b/templates/backOffice/default/ajax/product-attributes-tab.html index 25cdc502a..9e1d56feb 100644 --- a/templates/backOffice/default/ajax/product-attributes-tab.html +++ b/templates/backOffice/default/ajax/product-attributes-tab.html @@ -1,3 +1,6 @@ +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'} + {loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id}
diff --git a/templates/backOffice/default/ajax/product-related-tab.html b/templates/backOffice/default/ajax/product-related-tab.html index 8367e7f71..1d3efb78e 100644 --- a/templates/backOffice/default/ajax/product-related-tab.html +++ b/templates/backOffice/default/ajax/product-related-tab.html @@ -1,3 +1,6 @@ +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'} + {loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id}
diff --git a/templates/backOffice/default/ajax/template-attribute-list.html b/templates/backOffice/default/ajax/template-attribute-list.html index 619d13d53..514623814 100644 --- a/templates/backOffice/default/ajax/template-attribute-list.html +++ b/templates/backOffice/default/ajax/template-attribute-list.html @@ -1,3 +1,6 @@ +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'} +
{ifloop rel="free_attributes"}
diff --git a/templates/backOffice/default/ajax/template-feature-list.html b/templates/backOffice/default/ajax/template-feature-list.html index 24b50918e..08341beb1 100644 --- a/templates/backOffice/default/ajax/template-feature-list.html +++ b/templates/backOffice/default/ajax/template-feature-list.html @@ -1,3 +1,6 @@ +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'} +
{ifloop rel="free_features"} diff --git a/templates/backOffice/default/ajax/thelia_news_feed.html b/templates/backOffice/default/ajax/thelia_news_feed.html index fcc064ea9..dd857c56d 100644 --- a/templates/backOffice/default/ajax/thelia_news_feed.html +++ b/templates/backOffice/default/ajax/thelia_news_feed.html @@ -1,4 +1,7 @@ -{* this temlate is loaded via Ajax in the login page, to prevent login page slowdown *} +{* this template is loaded via Ajax in the login page, to prevent login page slowdown *} + +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='bo.default'}
{loop type="feed" name="thelia_feeds" url="http://thelia.net/Flux-rss.html?id_rubrique=8" limit="3"} diff --git a/templates/backOffice/default/configs/variables.conf b/templates/backOffice/default/configs/variables.conf index f41a1b61e..c2c81c01d 100644 --- a/templates/backOffice/default/configs/variables.conf +++ b/templates/backOffice/default/configs/variables.conf @@ -1,8 +1,11 @@ -#order +# Maximum number of lines in lists +# -------------------------------- max_displayed_orders = 20 max_displayed_customers = 20 -#order status +# order status - seems ununsed ? +# ------------------------------ + order_not_paid = 'warning' order_paid = 'success' order_processing = 'primary' diff --git a/templates/backOffice/default/translations.html b/templates/backOffice/default/translations.html index 9ceb8efd9..9e64b08d6 100644 --- a/templates/backOffice/default/translations.html +++ b/templates/backOffice/default/translations.html @@ -1,320 +1,347 @@ -{extends file="admin-layout.tpl"} - -{block name="page-title"}{intl l='Translations'}{/block} - -{block name="check-resource"}admin.configuration.variable{/block} -{block name="check-access"}update{/block} - -{block name="main-content"} -
- -
- - - -
-
-
- -
- {intl l="Translation"} -
- -
-
- -
- - {include - file = "includes/inner-form-toolbar.html" - close_url = {url path='/admin/configuration'} - } - - - -
-
-
- - - -
-
- - {if $item_to_translate == 'mo'} -
-
- - - -
-
- {else if $item_to_translate == 'fo'} -
-
- - - -
-
- {else if $item_to_translate == 'bo'} -
-
- - - -
-
- {else if $item_to_translate == 'ma'} -
-
- - - -
-
- {else if $item_to_translate == 'pf'} -
-
- - - -
-
- {/if} - - -
-
- - -
-
-
-
- - {* -- STRINGS TO TRANSLATE --------------------------------------------- *} - - {$currfile = false} - {$close_last_panel = false} - - {$idx = 0} - - {foreach $all_strings as $info} - - - - {$not_translated = empty($info.translation)} - - {if $view_missing_traductions_only != 1 || $not_translated } - - {* Create a liste of files names *} - - {if count($info.files) > 1} - {$label = {intl l='In pages:'}} - {capture name="banner" assign=file_names} -
    - {foreach $info.files as $file} -
  • {$file}
  • - {/foreach} -
- {/capture} - {else} - {$label = {intl l='In page'}} - {$file_names = $info.files.0} - {/if} - - {* Display current file liste, if required *} - - {if $file_names != $currfile} - - {if $currfile !== false} - {* Close current panel *} -
- {$close_last_panel = false} - {/if} - - {$currfile = $file_names} - -
-
- {loop name="lang_list" type="lang" id=$edit_language_id} - {$TITLE} - {/loop} - - {$label} {$file_names nofilter} - -
- - - - {$close_last_panel = true} - {/if} - - - - - - - - {else} - - {* Text is not displayed, put it in a hidden field *} - - - {/if} - - {$idx = $idx + 1} - {/foreach} - - {if isset($all_strings) } - - {if empty($all_strings) } -
- {intl l='Did not found any text to translate. It\'s probably normal. If not, please be sure to use Smarty\'s "intl" function in templates, or the Translator::trans() method in PHP files.'} -
- {else if $view_missing_traductions_only == 1 && $currfile == false } -
- {intl l='Congratulations, all text is now translated !'} -
- {/if} - - {if $close_last_panel} - {* close the last panel *} -
- {$info.text} - - - {if $info.dollar} -
- {intl l='Warning'} - {intl l='Il seems that this string contains a Smarty variable ($). If \'s the case, it cannot be transleted properly.'} -
- {/if} -
-
- - -
-
- {/if} - {/if} - - {if $max_input_vars_warning} -
- {intl l='Cannot translate all fields. According to your PHP configuration, forms cannot contains more than %current_max_input_vars input fields, but at least %required_max_input_vars are required. Please change the value of max_input_vars in your PHP configuration of change the translation file by hand.' - current_max_input_vars=$current_max_input_vars - required_max_input_vars=$required_max_input_vars - } -
- {/if} - - -
-
-
-
- -
-
-
-{/block} - -{block name="javascript-initialization"} - -{/block} - -{block name="javascript-last-call"} - {module_include location='translations-js'} -{/block} +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Translations'}{/block} + +{block name="check-resource"}admin.configuration.variable{/block} +{block name="check-access"}update{/block} + +{block name="main-content"} +
+ +
+ + + +
+
+
+ +
+ {intl l="Translation"} +
+ +
+
+
+
+ + {include + file = "includes/inner-form-toolbar.html" + close_url = {url path='/admin/configuration'} + } + + + +
+
+
+ + + +
+
+ + {if $item_to_translate == 'mo'} +
+
+ + + +
+
+ {else if $item_to_translate == 'fo'} +
+
+ + + +
+
+ {else if $item_to_translate == 'bo'} +
+
+ + + +
+
+ {else if $item_to_translate == 'ma'} +
+
+ + + +
+
+ {else if $item_to_translate == 'pf'} +
+
+ + + +
+
+ {/if} + + {if $item_to_translate == 'mo' && $item_name != ''} +
+
+ + + +
+
+ {/if} +
+ +
+
+
+ +
+
+
+
+ + {* -- STRINGS TO TRANSLATE --------------------------------------------- *} + + {$currfile = false} + {$close_last_panel = false} + + {$idx = 0} + + {foreach $all_strings as $info} + + + + {$not_translated = empty($info.translation)} + + {if $view_missing_traductions_only != 1 || $not_translated } + + {* Create a liste of files names *} + + {if count($info.files) > 1} + {$label = {intl l='In pages:'}} + {capture name="banner" assign=file_names} +
    + {foreach $info.files as $file} +
  • {$file}
  • + {/foreach} +
+ {/capture} + {else} + {$label = {intl l='In page'}} + {$file_names = $info.files.0} + {/if} + + {* Display current file liste, if required *} + + {if $file_names != $currfile} + + {if $currfile !== false} + {* Close current panel *} +
+ {$close_last_panel = false} + {/if} + + {$currfile = $file_names} + +
+
+ {loop name="lang_list" type="lang" id=$edit_language_id} + {$TITLE} + {/loop} + + {$label} {$file_names nofilter} + +
+ + + + {$close_last_panel = true} + {/if} + + + + + + + + {else} + + {* Text is not displayed, put it in a hidden field *} + + + {/if} + + {$idx = $idx + 1} + {/foreach} + + {if isset($all_strings) } + + {if empty($all_strings) } +
+ {intl l='Did not found any text to translate. It\'s probably normal. If not, please be sure to use Smarty\'s "intl" function in templates, or the Translator::trans() method in PHP files.'} +
+ {else if $view_missing_traductions_only == 1 && $currfile == false } +
+ {intl l='Congratulations, all text is now translated !'} +
+ {/if} + + {if $close_last_panel} + {* close the last panel *} +
+ {$info.text} + + + {if $info.dollar} +
+ {intl l='Warning'} + {intl l='Il seems that this string contains a Smarty variable ($). If \'s the case, it cannot be transleted properly.'} +
+ {/if} +
+
+ + +
+
+ {/if} + {/if} + + {if $max_input_vars_warning} +
+ {intl l='Cannot translate all fields. According to your PHP configuration, forms cannot contains more than %current_max_input_vars input fields, but at least %required_max_input_vars are required. Please change the value of max_input_vars in your PHP configuration of change the translation file by hand.' + current_max_input_vars=$current_max_input_vars + required_max_input_vars=$required_max_input_vars + } +
+ {/if} + + +
+
+
+
+ +
+
+
+{/block} + +{block name="javascript-initialization"} + +{/block} + +{block name="javascript-last-call"} + {module_include location='translations-js'} +{/block} diff --git a/templates/frontOffice/default/ajax/order-delivery-module-list.html b/templates/frontOffice/default/ajax/order-delivery-module-list.html index be05c35e3..ecc37669d 100644 --- a/templates/frontOffice/default/ajax/order-delivery-module-list.html +++ b/templates/frontOffice/default/ajax/order-delivery-module-list.html @@ -1,3 +1,6 @@ +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='fo.default'} + {form name="thelia.order.delivery"} {loop type="delivery" name="deliveries" force_return="true" country=$country} diff --git a/templates/frontOffice/default/layout.tpl b/templates/frontOffice/default/layout.tpl index 8aba0bb48..ae7de6894 100644 --- a/templates/frontOffice/default/layout.tpl +++ b/templates/frontOffice/default/layout.tpl @@ -1,449 +1,451 @@ - - - -{* Declare assets directory, relative to template base directory *} -{declare_assets directory='assets'} -{block name="no-return-functions"}{/block} -{assign var="store_name" value="{config key="store_name"}"} -{if not $store_name}{assign var="store_name" value="{intl l='Thelia V2'}"}{/if} - -{* paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither *} - - - - - - - {* Test if javascript is enabled *} - - - - - {* Page Title *} - {block name="page-title"}{strip}{if $page_title}{$page_title}{elseif $breadcrumbs}{foreach from=$breadcrumbs|array_reverse item=breadcrumb}{$breadcrumb.title|unescape} - {/foreach}{$store_name}{/if}{/strip}{/block} - - {* Meta Tags *} - - - - {block name="meta"} - - - {/block} - - {* Stylesheets *} - {stylesheets file='assets/css/styles.css'} - - {/stylesheets} - - {block name="stylesheet"}{/block} - - {* Favicon *} - {images file='assets/img/favicon.ico'}{/images} - {images file='assets/img/favicon.png'}{/images} - - {* HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries *} - - - - - - -{intl l="Skip to content"} - -
- -
- - - - - - -
- -
-
- {block name="breadcrumb"}{include file="misc/breadcrumb.tpl"}{/block} -
{block name="main-content"}{/block}
-
-
- - - -
- -{block name="before-javascript-include"}{/block} - - - - - - - - -{javascripts file='assets/js/bootstrap/bootstrap.js'} - -{/javascripts} - -{javascripts file='assets/js/plugins/bootbox/bootbox.js'} - -{/javascripts} - -{block name="after-javascript-include"}{/block} - -{block name="javascript-initialization"}{/block} - - -{javascripts file='assets/js/script.js'} - -{/javascripts} - + + + +{* Declare assets directory, relative to template base directory *} +{declare_assets directory='assets'} +{* Set the default translation domain, that will be used by {intl} when the 'd' parameter is not set *} +{default_translation_domain domain='fo.default'} +{block name="no-return-functions"}{/block} +{assign var="store_name" value="{config key="store_name"}"} +{if not $store_name}{assign var="store_name" value="{intl l='Thelia V2'}"}{/if} + +{* paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither *} + + + + + + + {* Test if javascript is enabled *} + + + + + {* Page Title *} + {block name="page-title"}{strip}{if $page_title}{$page_title}{elseif $breadcrumbs}{foreach from=$breadcrumbs|array_reverse item=breadcrumb}{$breadcrumb.title|unescape} - {/foreach}{$store_name}{/if}{/strip}{/block} + + {* Meta Tags *} + + + + {block name="meta"} + + + {/block} + + {* Stylesheets *} + {stylesheets file='assets/css/styles.css'} + + {/stylesheets} + + {block name="stylesheet"}{/block} + + {* Favicon *} + {images file='assets/img/favicon.ico'}{/images} + {images file='assets/img/favicon.png'}{/images} + + {* HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries *} + + + + + + +{intl l="Skip to content"} + +
+ +
+ + + + + + +
+ +
+
+ {block name="breadcrumb"}{include file="misc/breadcrumb.tpl"}{/block} +
{block name="main-content"}{/block}
+
+
+ + + +
+ +{block name="before-javascript-include"}{/block} + + + + + + + + +{javascripts file='assets/js/bootstrap/bootstrap.js'} + +{/javascripts} + +{javascripts file='assets/js/plugins/bootbox/bootbox.js'} + +{/javascripts} + +{block name="after-javascript-include"}{/block} + +{block name="javascript-initialization"}{/block} + + +{javascripts file='assets/js/script.js'} + +{/javascripts} + \ No newline at end of file