Таким образом, это вызовет огромный резонанс и пойдет на спад у каждого разработчика Magento - но у нас есть надежный процесс для создания тем - который не использует local.xml (подробнее об этом позже).
Мы всегда отрабатываем base/default
(и enterprise/default
для EE) шаблон - но обнуляем CSS. Даже при том, что все проекты не особенно подходят для структурного макета ванильного магазина Magento - мы считаем хорошей практикой использовать эту default
тему в качестве отправной точки; мы можем удалить неиспользуемые методы / циклы / HTML и т. д. при необходимости во время шаблонов.
При запуске темы
Для EE
Сначала мы устанавливаем это расширение , чтобы получить уровень отката темы - когда мы позже удалим скопированные файлы темы.
Посылка
Сначала мы создаем пакет и копируем всю base/default
тему; так, например (скажем, это был наш собственный сайт, мы бы назвали пакет sonassi
)
cd ./app/design/frontend
mkdir sonassi
cp -par base/default sonassi/default
mkdir sonassi/default/layout/custom
Шаблон
Конечная цель заключается в том, что нам не нужно копировать и вставлять каждый изменяемый файл всякий раз, когда нам это нужно, мы просто редактируем файл в теме.
Но каждый раз, когда мы редактируем файл, мы удаляем заголовки Magento Commerce и добавляем соответствующий заголовок / идентификатор, чтобы пометить файл как пользовательский шаблон, обычно что-то вроде ...
/*
* @category Template
* @package sonassi_default
* @copyright Copyright (c) 2013 Sonassi
*/
Этот заголовок служит цели позже, когда мы делаем окончательную очистку шаблона. Поскольку мы сделаем рекурсив diff
для base/default/template
каталога и sonassi/default/template
каталога - затем удалим все, что не было изменено.
Таким образом, остаются только измененные файлы, и общий пакет был уменьшен до минимума измененных файлов.
Файлы макетов
Мы используем собственный стандартный модуль ядра sonassi.core
. Да, мы всегда ставим перед пространством имен модуля уникальный идентификатор - он предотвращает конфликты, когда другие компании выбирают одно и то же имя (например, fishpig / wordpress и sonassi / wordpress)
Методология нолокального макета
<core>
<rewrite>
<layout>Sonassi_Core_Model_Core_Layout</layout>
<layout_update>Sonassi_Core_Model_Core_Layout_Update</layout_update>
</rewrite>
</core>
Затем два магических класса, которые добавляют функциональность, которая больше никогда не понадобится local.xml
,
class Sonassi_Core_Model_Core_Layout
extends Mage_Core_Model_Layout
{
/**
* Loyout xml generation
*
* @return Mage_Core_Model_Layout
*/
public function generateXml()
{
$xml = $this->getUpdate()->asSimplexml();
$removeInstructions = $xml->xpath("//remove");
if (is_array($removeInstructions)) {
foreach ($removeInstructions as $infoNode) {
$attributes = $infoNode->attributes();
$blockName = (string)$attributes->name;
if ($blockName) {
$unremoveNodes = $xml->xpath("//unremove[@name='".$blockName."']");
if (is_array($unremoveNodes) && count($unremoveNodes) > 0) {
continue;
}
$ignoreNodes = $xml->xpath("//block[@name='".$blockName."']");
if (!is_array($ignoreNodes)) {
continue;
}
$ignoreReferences = $xml->xpath("//reference[@name='".$blockName."']");
if (is_array($ignoreReferences)) {
$ignoreNodes = array_merge($ignoreNodes, $ignoreReferences);
}
foreach ($ignoreNodes as $block) {
if ($block->getAttribute('ignore') !== null) {
continue;
}
$acl = (string)$attributes->acl;
if ($acl && Mage::getSingleton('admin/session')->isAllowed($acl)) {
continue;
}
if (!isset($block->attributes()->ignore)) {
$block->addAttribute('ignore', true);
}
}
}
}
}
$this->setXml($xml);
return $this;
}
}
а также
class Sonassi_Core_Model_Core_Layout_Update
extends Mage_Core_Model_Layout_Update
{
public function getFileLayoutUpdatesXml($area, $package, $theme, $storeId = null)
{
if (null === $storeId) {
$storeId = Mage::app()->getStore()->getId();
}
/* @var $design Mage_Core_Model_Design_Package */
$design = Mage::getSingleton('core/design_package');
$layoutXml = null;
$elementClass = $this->getElementClass();
$updatesRoot = Mage::app()->getConfig()->getNode($area.'/layout/updates');
Mage::dispatchEvent('core_layout_update_updates_get_after', array('updates' => $updatesRoot));
$updateFiles = array();
foreach ($updatesRoot->children() as $updateNode) {
if ($updateNode->file) {
$module = $updateNode->getAttribute('module');
if ($module && Mage::getStoreConfigFlag('advanced/modules_disable_output/' . $module, $storeId)) {
continue;
}
$updateFiles[] = (string)$updateNode->file;
// custom theme XML contents
$updateFiles[] = 'custom/'.(string)$updateNode->file;
// custom theme XML override
$updateFiles[] = 'local/'.(string)$updateNode->file;
}
}
// custom local layout updates file - load always last
$updateFiles[] = 'local.xml';
$layoutStr = '';
foreach ($updateFiles as $file) {
$filename = $design->getLayoutFilename($file, array(
'_area' => $area,
'_package' => $package,
'_theme' => $theme
));
if (!is_readable($filename)) {
continue;
}
$fileStr = file_get_contents($filename);
$fileStr = str_replace($this->_subst['from'], $this->_subst['to'], $fileStr);
$fileXml = simplexml_load_string($fileStr, $elementClass);
if (!$fileXml instanceof SimpleXMLElement) {
continue;
}
$layoutStr .= $fileXml->innerXml();
}
$layoutXml = simplexml_load_string('<layouts>'.$layoutStr.'</layouts>', $elementClass);
return $layoutXml;
}
}
Два вышеупомянутых класса добавляют функциональность в Magento, чтобы вы могли расширять, но не перезаписывать XML-файл макета. Расширяемость макета XML важен для нас, так как это позволяет нам по- прежнему поддерживать тот же разделение файла catalog.xml
, и cms.xml
т.д. - но только нужно добавить короткие части макета XML для управления блоками (вставка / клон / удалить).
local.xml
Методологии является то , что вы просто введите переопределение изменения в один громоздкий неуправляемый файл.
В nolocal
методологии означает , что вместо того , чтобы поместить все изменения в одном файле, поместить их в файл с соответствующим именем файла , что он модифицирует (например. catalog.xml
) - просто создать новый файл sonassi/default/layout/custom/catalog.xml
- с * только модификациями .
Опять же, как только мы закончим создание шаблона, мы можем просто удалить содержимое, за sonassi/default/layout
исключением custom
каталога. Таким образом, как и в случае с шаблоном, у нас есть легкий расширенный шаблон, основанный на базовых шаблонах.
Таблицы стилей
Мы удаляем их всех. Мы не копируем их в каталог CSS нашего пакета. Мы скопируем в JS, и все - каталог images
and CSS
будет пуст с самого начала.
Поскольку в настоящее время мы используем SASS, у нас будет еще один каталог ( scss
) для предварительно обработанного CSS - и вывод в основной файл (ы) style / print CSS.
Очистка шаблона
Итак, как мы уже упоминали, после того, как тема шаблона завершена, вы можете очистить ее - удалить неизмененные файлы и сократить ее до минимума.
cd ./app/design/frontend
PREFIX="cleantheme_"
THEME="sonassi/default"
diff -BPqr "base/default/template" "$THEME/template" | \
awk '{print $4}' | \
while read FILE; do
DIR=$(dirname "$FILE")
[ -d "$PREFIX$DIR" ] || mkdir -p "$PREFIX$DIR"
[ -f "$PREFIX$FILE" ] || cp -pa "$FILE" "$PREFIX$FILE"
done
cp -par "$THEME/layout" "$PREFIX$THEME/"
Так почему нет local.xml
?
Это не для вас - это для третьих лиц, так же, community
как для вас и local
для третьих лиц. Это возврат, в крайнем случае, конечный пункт назначения для переопределений.
Структурирование XML таким образом поддерживает его в соответствии с тем, как Magento изначально настраивал структуру каталогов и файлов. Плюс, для непрерывности разработки - это просто имеет больше смысла, намного легче усваивается и не добавляет заметных накладных расходов.
Magento - странный продукт, сообщество разработало собственную лучшую практику, основанную на здравом смысле и подражающую действиям основной команды Magento. Так что официального пути не существует (только когда единорог прибегает к документации Magento-1) ; но это наш путь.
Так что я бы даже растянуть сказать , что это не ответ, его только один из многих способов решения с которыми нередко сталкиваются вызова. Хотя я хотел бы думать, что наш метод является лучшим.
Содержимое, полученное с радостью от sonassi.com