Magento 2'de Temanın Üst Öğesini Güncellemenin Doğru Yolu


14

Magento 2'de temanın theme.xmldosyasında bir ana tema belirtebilirsiniz .

<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Theme Title</title>
    <parent>Package/base-theme</parent>
    <media>
        <preview_image>media/preview.jpg</preview_image>
    </media>
</theme>

Magento bir temayı ilk gördüğünde parent_id, themetabloya a ayarlamak için bu değeri kullanır . Bu, bir temanın ebeveyni olduğu gerçeğin kaynağıdır.

Ancak, sisteme bir tema eklendikten sonra bu değeri değiştirmeye çalışırsanız , Magento parent_idsütunu güncelleyemez ve somutlaştırılmış Magento\Theme\Model\Themenesneler yine de orijinal ana temaya sahip olur. (Önbelleği temizleseniz bile.)

Ben parent_idbir hack gibi görünüyor - değeri elle değiştirerek bunu düzeltebilirsiniz . parent_idNormalde Magento'nun çekirdek kodunda nerede ayarlanır ve hangi kullanıcı eylemleri bunu tetikler? yani Magento'ya "lütfen bu temayı yeniden yükleyin" demenin bir yolu var mı?


2
Evet, bunu da fark ettim ve tema kaydedildikten sonra bunu değiştirmenin tek yolu veritabanını doğrudan değiştirmek. Muhtemelen bir böcek mi?
Gareth Daine

Yanıtlar:


2

20160310 GÜNCELLEME

Sonuç

Her zaman updateTheme()toplama yoluyla veya koleksiyondan (DB aracılığıyla) ayarlanırsa ,appState->getMode() == AppState::MODE_PRODUCTION

Cevap

Soruya cevap vermek için theme.xml dosyasını yeniden Magento almanın yolu nedir cevap:

Uygulamanın durumunu ayarlama developerkullanarak SetEnv MAGE_MODE developeriçinde .htaccess(veya nginx eşdeğer) ve daha sonra yönetici alanına giriş (veya herhangi bir yönetici rotasını yenilemek) tetiğe Magento\Theme\Model\Theme\Plugin\Registration::beforeDispatch().

Veritabanındaki tema tablosu,

\\Magento\Theme\Model\Theme\Plugin\Registration::updateThemeData()
\\...
$themeData->setParentId($parentTheme->getId());`.
\\...

Ayrıntılar için aşağıdaki analize bakın.

analiz

Vay canına Magento 2 kodu benim için gerçekten karmaşık görünüyor. Eğer bu fonksiyonu inceledik beforeDispatch()Aramaların updateThemeData()ama sadeceif ($this->appState->getMode() != AppState::MODE_PRODUCTION)

//namespace: namespace Magento\Theme\Model\Theme\Plugin;
//class: Registration
//file: app/code/Magento/Theme/Model/Theme/Plugin/Registration.php 

     /**
     * Add new theme from filesystem and update existing
     *
     * @param AbstractAction $subject
     * @param RequestInterface $request
     *
     * @return void
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function beforeDispatch(
        AbstractAction $subject,
        RequestInterface $request
    ) {
        try {
            if ($this->appState->getMode() != AppState::MODE_PRODUCTION) {
                $this->themeRegistration->register();
                $this->updateThemeData();
            }
        } catch (LocalizedException $e) {
            $this->logger->critical($e);
        }
    }

Muhtemelen bu koddan geçtiniz.

beforeDispatch()yalnızca yönetici yollarıyla çağrılır, ön uç yollarda çağrılmaz. İşte bir iz:

#0 [internal function]: Magento\Theme\Model\Theme\Plugin\Registration->beforeDispatch(Object(Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor), Object(Magento\Framework\App\Request\Http))
#1 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(122): call_user_func_array(Array, Array)
#2 \magento2\var\generation\Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor.php(39): Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor->___callPlugins('dispatch', Array, Array)
#3 \magento2\lib\internal\Magento\Framework\App\FrontController.php(55): Magento\Backend\Controller\Adminhtml\Dashboard\Index\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#4 [internal function]: Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#5 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(74): call_user_func_array(Array, Array)
#6 \magento2\lib\internal\Magento\Framework\Interception\Chain\Chain.php(70): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#7 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(136): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'install')
#8 \magento2\lib\internal\Magento\Framework\Module\Plugin\DbStatusValidator.php(69): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#9 [internal function]: Magento\Framework\Module\Plugin\DbStatusValidator->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#10 \magento2\lib\internal\Magento\Framework\Interception\Interceptor.php(141): call_user_func_array(Array, Array)
#11 \magento2\var\generation\Magento\Framework\App\FrontController\Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, Array)
#12 \magento2\lib\internal\Magento\Framework\App\Http.php(115): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#13 \magento2\lib\internal\Magento\Framework\App\Bootstrap.php(258): Magento\Framework\App\Http->launch()
#14 \magento2\index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))

Aslında bu nugget içeren beforeDispatch()çağrıları görüyorum updateThemeData():

//namespace: namespace Magento\Theme\Model\Theme\Plugin;
//class: Registration
//file: app/code/Magento/Theme/Model/Theme/Plugin/Registration.php 
//function: updateThemeData()

//...
            if ($themeData->getParentTheme()) {
                $parentTheme = $this->themeLoader->getThemeByFullPath(
                    $themeData->getParentTheme()->getFullPath()
                );
                $themeData->setParentId($parentTheme->getId());
            }
//...

Aslında (nihayet) bir yapılandırma XML yoluna başvuruyor gibi görünüyor, $themeData->getParentTheme()->getFullPath()ancak bu işlev hala kullanıyor $themeData->getParentTheme(). Oh mantık ' Koleksiyonda bir parentId (DB aracılığıyla) olan kayıtlı bir tema güncelleştiriyorsanız, o zaman yapılandırma üst bir yol aramak ve koleksiyonu güncelleştirmek olduğunu düşünüyorum .Belki de budur.

Aksi takdirde tema arayüzünde bildirilen nasıl Magento\Theme\Model\Theme::getParentTheme()uygular konusunda tam bir kayıp var getParentId(). Elbette sihir değil. Dediğin gibi ya koleksiyon yoluyla DB ya da temanın yapılandırma XML yolundan gelmesi gerekiyor (değişti ya da henüz tanımlanmadıysa) ama bir tanımı bulamıyorum getParentId(). Belki her zaman updateTheme()OR üzerinden koleksiyonundan (DB yoluyla) ayarlanırsa çok kötü appState->getMode() == AppState::MODE_PRODUCTION.

updateThemeData()Bazı günlük çıktıları ekleyerek içeriden bilgi toplamak için yararlı buldum :

//namespace: namespace Magento\Theme\Model\Theme\Plugin;
//class: Registration
//file: app/code/Magento/Theme/Model/Theme/Plugin/Registration.php 
//function: updateThemeData()

//...
            if ($themeData->getParentTheme()) {
                $parentTheme = $this->themeLoader->getThemeByFullPath(
                    $themeData->getParentTheme()->getFullPath()
                );
            $this->logger->addDebug("Theme parent full path ".$themeData->getParentTheme()->getFullPath());
            $this->logger->addDebug("Theme parent new ID ".$parentTheme->getId());                    $themeData->setParentId($parentTheme->getId());
            }
//...

Hangi giriş yapacak /var/log/debug.log. Uygulama durumu olarak ayarlandığında developer, ana kimliğin değiştirilip değiştirilmediğine bakılmaksızın her yönetici sayfasında yenilendiğini her zaman görebilirsiniz theme.xml. Uygulama durumu productionile fonksiyon asla çalıştırılır, bu yüzden sonuçlandırıyorum:

Her zaman updateTheme()koleksiyondan OR aracılığıyla (DB aracılığıyla) ayarlanır .appState->getMode() == AppState::MODE_PRODUCTION

Bence hepiniz developeruygulama durumundasınız. defaultuygulama durumu updateThemeData()elbette çok tetikleyecektir . Daha fazla hata ayıklamada olan Luma'nın ana teması için tema tam yolunu kaydettim frontend/Magento/blank. Başkent Mbeni şaşırttı, belki de dikkat edilmesi gereken bir şey.


0

Yukarıdakiler benim için işe yaramadı, bu yüzden hack ile gittim.

Umarım birine yardımcı olur.

using the command line

 mysql

 SHOW databases;

 use magento; (or whatever your DB's name is)

 SHOW tables

 SELECT * FROM theme; 

(Check the **parent_id** of theme in question, it should be the same number as **theme_id** of theme you want as the parent)

değilse, değiştirin.

 UPDATE theme SET parent_id  = '[value]' WHERE theme_title = '[Theme name]';

then quit mysql;

 bin/magento setup:static-content:deploy 

veya

grunt clean:[theme] (For example:  grunt clean:blank)

grunt exec:[theme]

grunt less:[theme]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.