Magento 2 में थीम के जनक को अपडेट करने का सही तरीका


14

Magento 2 में, आप एक विषय की theme.xmlफ़ाइल में एक मूल विषय निर्दिष्ट कर सकते हैं ।

<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 एक विषय को देखता है, यह तालिका parent_idमें सेट करने के लिए इस मान का उपयोग करता है theme। यह सत्य का स्रोत है जहां एक विषय के माता-पिता हैं।

हालाँकि, यदि आप थीम में सिस्टम में जोड़े जाने के बाद इस मान को बदलने का प्रयास करते हैं , तो Magento parent_idकॉलम अपडेट करने में विफल रहता है , और त्वरित Magento\Theme\Model\Themeऑब्जेक्ट्स में अभी भी मूल मूल विषय होगा। (भले ही आप कैश साफ़ करें।)

मैं इसे मैन्युअल रूप से parent_idमान बदलकर ठीक कर सकता हूं - जो एक हैक की तरह लगता है। parent_idमैगेंटो के मूल कोड में सामान्य रूप से कहां सेट किया गया है, और उपयोगकर्ता की गतिविधियां इसे क्या ट्रिगर करती हैं? मैगेंटो "कृपया इस विषय को फिर से लोड करें" बताने का एक तरीका है


2
हां, मैंने इस पर भी गौर किया है और विषय पंजीकृत होने के बाद इसे संशोधित करने का एकमात्र तरीका मैंने डेटाबेस को सीधे संशोधित करना है। संभवतः एक बग?
गारेथ डाइन

जवाबों:


2

20160310 पर अद्यतन

निष्कर्ष

यह हमेशा या तो updateTheme()संग्रह के माध्यम से या डीबी के माध्यम से सेट किया जाता है यदि आपकेappState->getMode() == AppState::MODE_PRODUCTION

उत्तर

इस सवाल का जवाब देने के लिए कि मैगेंटो को फिर से लोड करने का तरीका क्या है। इस उत्तर को फाइल करने के लिए देखें:

करने के लिए आवेदन स्थिति सेट developerका उपयोग कर SetEnv MAGE_MODE developerमें .htaccess(या nginx समकक्ष) और उसके बाद व्यवस्थापक क्षेत्र में प्रवेश करें (या किसी भी व्यवस्थापक मार्ग ताज़ा करें) ट्रिगर करने के लिए Magento\Theme\Model\Theme\Plugin\Registration::beforeDispatch()

डेटाबेस में विषय तालिका के कारण अद्यतन किया जाता है

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

विवरण के लिए नीचे विश्लेषण देखें।

विश्लेषण

वाह Magento 2 कोड वास्तव में मेरे लिए जटिल लगता है। क्या आपने इस फ़ंक्शन का अध्ययन किया है beforeDispatch()जो updateThemeData()केवल कॉल करता हैif ($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);
        }
    }

संभवतः आप इस कोड के माध्यम से रहे हैं।

beforeDispatch()केवल व्यवस्थापक मार्गों के माध्यम से कहा जाता है और फ्रंट-एंड मार्गों पर नहीं। यहाँ एक निशान है:

#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))

वास्तव में मुझे ऐसी beforeDispatch()कॉल दिखाई देती हैं 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());
            }
//...

जो वास्तव में (अंततः) एक विन्यास XML पथ को संदर्भित $themeData->getParentTheme()->getFullPath()करता है, लेकिन वह फ़ंक्शन अभी भी उपयोग करता है $themeData->getParentTheme()। ओह, मुझे लगता है कि तर्क यह है कि ' अगर मैं एक पंजीकृत विषय को अपडेट कर रहा हूं, जिसमें संग्रह में एक DBId है (DB के माध्यम से) तो विन्यास में एक मूल पथ की तलाश करें और संग्रह को अपडेट करें '।तो शायद यह है।

अन्यथा मैं पूरी तरह से नुकसान में हूं कि थीम इंटरफ़ेस में कैसे Magento\Theme\Model\Theme::getParentTheme()लागू getParentId()किया जाता है। निश्चित रूप से यह जादू नहीं है। जैसा कि आप कहते हैं कि इसे या तो डीबी से संग्रह के माध्यम से या थीम के कॉन्फ़िगर एक्सएमएल पथ (यदि यह अभी तक परिभाषित नहीं है या इसे परिभाषित नहीं किया गया है) से आने की आवश्यकता है, लेकिन मुझे इसकी परिभाषा नहीं मिल सकती है getParentId()। शायद यह हमेशा updateTheme()संग्रह के माध्यम से या (डीबी के माध्यम से) सेट किया जाता है तो बहुत बुरा अगर आपके appState->getMode() == AppState::MODE_PRODUCTION

मुझे 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()
                );
            $this->logger->addDebug("Theme parent full path ".$themeData->getParentTheme()->getFullPath());
            $this->logger->addDebug("Theme parent new ID ".$parentTheme->getId());                    $themeData->setParentId($parentTheme->getId());
            }
//...

जो लॉग इन करेगा /var/log/debug.log। एप्लिकेशन स्टेट सेट के साथ developerमैं देख सकता हूं कि पैरेंट आईडी हमेशा हर एडमिन पेज रिफ्रेश पर सेट होता है कि यह बदला गया था theme.xmlया नहीं। एप्लिकेशन स्टेट productionके साथ फंक्शन कभी नहीं चलाया जाता है इसलिए मैं निष्कर्ष निकालता हूं:

यह हमेशा updateTheme()या तो संग्रह के माध्यम से (DB के माध्यम से) सेट किया जाता है, तो बहुत बुरा अगर आपकेappState->getMode() == AppState::MODE_PRODUCTION

मुझे लगता है कि आप शायद सभी developerराज्य में हैं। defaultएप्लिकेशन राज्य updateThemeData()निश्चित रूप से भी ट्रिगर होगा । आगे डिबगिंग में मैंने लूमा के मूल विषय के लिए थीम पूर्ण पथ को लॉग किया frontend/Magento/blank। राजधानी Mने मुझे बहुत आश्चर्यचकित किया कि शायद बाहर देखने के लिए कुछ है।


0

ऊपर मेरे लिए काम नहीं कर रहा था, इसलिए मैं हैक के साथ चला गया।

आशा है कि यह किसी की मदद करता है।

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)

यदि यह नहीं है, तो इसे बदल दें।

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

then quit mysql;

 bin/magento setup:static-content:deploy 

या

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

grunt exec:[theme]

grunt less:[theme]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.