Cách chính xác để cập nhật Phụ huynh của chủ đề trong Magento 2


14

Trong Magento 2, bạn có thể chỉ định chủ đề gốc trong theme.xmltệp của chủ đề .

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

Lần đầu tiên Magento nhìn thấy một chủ đề, nó sử dụng giá trị này để đặt parent_idtrong themebảng. Đây là nguồn sự thật cho việc cha mẹ của một chủ đề.

Tuy nhiên, nếu bạn cố gắng thay đổi giá trị này sau khi một chủ đề được thêm vào hệ thống , Magento không cập nhật được parent_idcột và Magento\Theme\Model\Themecác đối tượng được khởi tạo vẫn sẽ có chủ đề gốc ban đầu. (Ngay cả khi bạn xóa bộ nhớ cache.)

Tôi có thể khắc phục điều này bằng cách thay đổi parent_idgiá trị theo cách thủ công - có vẻ như là một hack. Trường hợp parent_idthường được đặt trong mã lõi của Magento và hành động nào của người dùng kích hoạt điều này? tức là có một cách để nói với Magento "vui lòng tải lại chủ đề này"


2
Vâng, tôi cũng nhận thấy điều này và cách duy nhất tôi tìm thấy để sửa đổi điều này sau khi chủ đề đã được đăng ký là sửa đổi cơ sở dữ liệu trực tiếp. Có thể là một lỗi?
Gareth Daine

Câu trả lời:


2

CẬP NHẬT TẠI 20160310

Phần kết luận

Nó luôn được đặt qua updateTheme()hoặc từ bộ sưu tập (thông qua DB) nếuappState->getMode() == AppState::MODE_PRODUCTION

Câu trả lời

Để trả lời câu hỏi Cách nào để Magento tải lại tệp theme.xml , câu trả lời là:

Đặt trạng thái ứng dụng thành developersử dụng SetEnv MAGE_MODE developertrong .htaccess(hoặc nginx tương đương) và sau đó đăng nhập vào khu vực quản trị (hoặc làm mới bất kỳ tuyến quản trị nào) để kích hoạt Magento\Theme\Model\Theme\Plugin\Registration::beforeDispatch().

Bảng chủ đề trong cơ sở dữ liệu được cập nhật do

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

Xem phân tích dưới đây để biết chi tiết.

Phân tích

Wow mã Magento 2 có vẻ thực sự phức tạp đối với tôi. Bạn đã nghiên cứu chức năng này beforeDispatch()mà gọi updateThemeData()nhưng chỉ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);
        }
    }

Có lẽ bạn đã được thông qua mã này.

beforeDispatch()chỉ được gọi thông qua các tuyến quản trị và không phải trên các tuyến đầu. Đây là một dấu vết:

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

Trên thực tế tôi thấy beforeDispatch()các cuộc gọi updateThemeData()có chứa nugget này:

//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());
            }
//...

Có vẻ như thực sự (cuối cùng) đề cập đến một đường dẫn XML cấu hình $themeData->getParentTheme()->getFullPath()nhưng chức năng đó vẫn sử dụng $themeData->getParentTheme(). Ồ tôi nghĩ logic là ' Nếu tôi đang cập nhật một chủ đề đã đăng ký có cha mẹ trong bộ sưu tập (thông qua DB) thì hãy tìm đường dẫn cha mẹ trong cấu hình và cập nhật bộ sưu tập '.Vì vậy, có lẽ đây là nó.

Mặt khác, tôi hoàn toàn mất khả năng Magento\Theme\Model\Theme::getParentTheme()thực hiện getParentId()khai báo trong giao diện chủ đề. Chắc chắn đó không phải là phép thuật. Như bạn nói, nó cần đến từ DB thông qua bộ sưu tập hoặc từ đường dẫn XML cấu hình của chủ đề (nếu nó đã thay đổi hoặc chưa được xác định) nhưng tôi không thể tìm thấy định nghĩa getParentId(). Có thể nó luôn được đặt qua updateTheme()OR từ bộ sưu tập (qua DB) nên quá tệ nếu bạn appState->getMode() == AppState::MODE_PRODUCTION.

Tôi thấy nó hữu ích để lượm lặt thông tin từ bên trong updateThemeData()bằng cách thêm một số đầu ra nhật ký:

//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());
            }
//...

Mà sẽ đăng nhập /var/log/debug.log. Với trạng thái ứng dụng được đặt thành developertôi có thể thấy ID cha luôn được đặt trên mỗi lần làm mới trang quản trị cho dù nó có được thay đổi theme.xmlhay không. Với trạng thái ứng dụng production, hàm không bao giờ chạy được nên tôi kết luận:

Nó luôn được đặt qua updateTheme()OR từ bộ sưu tập (qua DB) nên quá tệ nếuappState->getMode() == AppState::MODE_PRODUCTION

Tôi nghĩ rằng bạn có thể là tất cả trong developertrạng thái ứng dụng. defaultTất nhiên, trạng thái ứng dụng sẽ kích hoạt updateThemeData(). Trong phần gỡ lỗi tiếp theo, tôi đã ghi lại đường dẫn đầy đủ của chủ đề cho chủ đề chính của Luma frontend/Magento/blank. Thủ đô Mlàm tôi ngạc nhiên vì vậy có lẽ một cái gì đó để coi chừng.


0

Ở trên dường như không làm việc cho tôi, vì vậy tôi đã đi với hack.

Hy vọng nó sẽ giúp được ai đó.

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)

Nếu không, thay đổi nó.

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

then quit mysql;

 bin/magento setup:static-content:deploy 

hoặc là

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

grunt exec:[theme]

grunt less:[theme]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.