วิธีที่ถูกต้องในการอัพเดทพาเรนต์ของธีมใน 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>

ครั้งแรกที่วีโอไอพีเห็นชุดรูปแบบจะใช้ค่านี้เพื่อตั้งค่าparent_idในthemeตาราง นี่คือที่มาของความจริงสำหรับผู้ปกครองของชุดรูปแบบ

อย่างไรก็ตามหากคุณพยายามเปลี่ยนค่านี้หลังจากที่เพิ่มธีมเข้าไปในระบบวีโอไอพีจะไม่สามารถอัปเดตparent_idคอลัมน์ได้และMagento\Theme\Model\Themeวัตถุอินสแตนซ์จะยังคงมีธีมหลักดั้งเดิมอยู่ (แม้ว่าคุณจะล้างแคช)

ฉันสามารถแก้ไขได้โดยเปลี่ยนparent_idค่าด้วยตนเอง- ดูเหมือนแฮ็ค parent_idโดยปกติจะตั้งอยู่ที่ไหนในรหัสหลักของ Magento และการกระทำของผู้ใช้ที่ทำให้เกิดสิ่งนี้ นั่นคือมีวิธีที่จะบอก Magento "โปรดโหลดชุดรูปแบบนี้อีกครั้ง"


2
ใช่ฉันได้สังเกตเห็นสิ่งนี้ด้วยและวิธีเดียวที่ฉันได้พบการแก้ไขนี้หลังจากที่ลงทะเบียนชุดรูปแบบคือการปรับเปลี่ยนฐานข้อมูลโดยตรง อาจเป็นข้อผิดพลาดหรือไม่?
Gareth Daine

คำตอบ:


2

อัปเดตเมื่อวันที่ 20160310

ข้อสรุป

มันถูกตั้งค่าอย่างใดอย่างหนึ่งผ่านupdateTheme()หรือจากคอลเลกชัน (ผ่าน DB) ถ้าของคุณappState->getMode() == AppState::MODE_PRODUCTION

ตอบ

ในการตอบคำถามวิธีที่ทำให้ Magento สามารถโหลดไฟล์ theme.xml ใหม่ได้คำตอบคือ:

ตั้งค่าสถานะโปรแกรมประยุกต์เพื่อdeveloperใช้SetEnv MAGE_MODE developerใน.htaccess(หรือ Nginx เทียบเท่า) และจากนั้นเข้าสู่พื้นที่ admin (หรือฟื้นฟูเส้นทางผู้ดูแลระบบใด ๆ ) 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 config $themeData->getParentTheme()->getFullPath()แต่ฟังก์ชั่นนั้นยังคงใช้$themeData->getParentTheme()อยู่ โอ้ฉันคิดว่าตรรกะคือ ' ถ้าฉันกำลังอัปเดตชุดรูปแบบที่ลงทะเบียนซึ่งมี parentId ในคอลเล็กชัน (ผ่านทาง DB) ให้ค้นหาพาเรนต์พาเรนต์ในการกำหนดค่าและอัปเดตคอลเลกชัน 'บางทีนี่อาจเป็น

มิฉะนั้นฉันจะสูญเสียอย่างสมบูรณ์เป็นวิธีMagento\Theme\Model\Theme::getParentTheme()การดำเนินการgetParentId()ซึ่งมีการประกาศในรูปแบบอินเตอร์เฟซ แน่นอนมันไม่ใช่เวทมนตร์ อย่างที่คุณบอกว่ามันต้องมาจาก DB ผ่านทางคอลเลกชันหรือจากพา ธ XML ของธีม (ถ้าเปลี่ยนไปหรือยังไม่ได้กำหนด) แต่ฉันหาคำจำกัดความgetParentId()ไม่ได้ บางทีมันอาจจะตั้งเสมอผ่านupdateTheme()หรือจากคอลเลกชัน (ผ่าน DB) 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()แน่นอนเกินไป ในการแก้จุดบกพร่องต่อไปฉันเข้าสู่ระบบธีมเส้นทางแบบเต็มสำหรับธีมแม่ของ Luma 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]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.