Cách ghi đè các khối trong v2.1


14

Tôi đang cố gắng ghi đè khối Topmenu trong Magento 2.1 nhưng không thể tìm thấy bất kỳ hướng dẫn nào để làm như vậy. Mọi thứ tôi tìm thấy ở đây và những nơi khác dường như chỉ áp dụng cho phiên bản 2.0 dường như sử dụng cấu trúc thư mục khác hoặc chỉ có các ví dụ mã một phần mà tôi mong muốn biết được ngữ cảnh phù hợp của chúng (mà tôi không biết).

Cấu trúc thư mục hiện tại của tôi cho một chủ đề tùy chỉnh là app/design/frontend/Vendor/theme_name. Trong phần này, tôi có các tệp đăng ký, chủ đề và trình soạn thảo cũng như các thư mục cho các mô-đun khác nhau, ví dụ Magento_ThemeMagento_Search.

Từ những gì tôi hiểu, tôi cần bắt đầu với một etc/di.xmltệp như bên dưới, được chỉnh sửa từ đây :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="Magento\Theme\Block\Html\Topmenu" type="[Namespace]\[Module]\Block\Html\Topmenu" />
</config>

Tôi cũng hiểu rằng bước tiếp theo là thêm một Block/Html/Topmenu.phptệp như bên dưới (một lần nữa được chỉnh sửa từ nguồn trên):

namespace [Namespace]\[Module]\Block\Html;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{

  protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
  {

  }

}

Tuy nhiên, tôi không rõ tôi nên sử dụng cái gì [Namespace][Module]hoặc nơi để đặt các tệp này. Tôi đã thử sử dụng tên nhà cung cấp và chủ đề, và đặt etcBlockcác thư mục vào app/design/frontend/Vendor/theme_name, cũng như đặt chúng vào app/design/frontend/Vendor/theme_name/Magento_Theme, sửa đổi các không gian tên thành Vendor\theme_name\Magento_Theme\Block\Html, nhưng không có tác dụng.

Nếu bất cứ ai có thể giúp giải thích chính xác những gì tôi cần làm để ghi đè khối Topmenu (và bằng cách suy luận bất kỳ khối nào khác) trong phiên bản 2.1, tôi sẽ được đánh giá cao.

Phụ lục

Tôi đã thử câu trả lời của Khoa TruongDinh nhưng nó không ảnh hưởng gì. Tôi đã sử dụng các tệp sau:

app/code/Vendor/MagentoTheme/Block/Html/Topmenu.php

<?php

namespace Vendor\MagentoTheme\Block\Html;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{

  protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
  {

    $html = '';

    if (!$child->hasChildren())
    {
      return $html;
    }

    $colStops = null;

    if ($childLevel == 0 && $limit)
    {
      $colStops = $this->_columnBrake($child->getChildren(), $limit);
    }

    // Added "test" class to test
    $html .= '<ul class="level' . $childLevel . ' test submenu">';
    $html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
    $html .= '</ul>';

    return $html;

  }

}

app/code/Vendor/MagentoTheme/composer.json

{
    "name": "vendor/magento-theme",
    "description": "",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",
        "magento/framework": "100.0.*"
    },
    "type": "magento2-module",
    "version": "100.0.1",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [ "registration.php" ],
        "psr-4": {
            "Vendor\\MagentoTheme\\": ""
        }
    }
}

app/code/Vendor/MagentoTheme/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="Magento\Theme\Block\Html\Topmenu" type="Vendor\MagentoTheme\Block\Html\Topmenu" />
</config>

app/code/Vendor/MagentoTheme/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_MagentoTheme" setup_version="1.0.0"></module>
</config>

app/code/Vendor/MagentoTheme/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
  \Magento\Framework\Component\ComponentRegistrar::MODULE,
  'Vendor_MagentoTheme',
  __DIR__
);

Sau đó tôi đã xóa nội dung của pub/static/frontend,var/generationvar/view_preprocessed, và đỏ ửng bộ nhớ cache Magento. Menu con không có lớp "kiểm tra" dự định được thêm vào:

<ul class="level0 submenu ui-menu ui-widget ui-widget-content ui-corner-all" role="menu" aria-expanded="false" style="display: none; top: 52.6719px; left: 487.5px;" aria-hidden="true">...</ul>

Bạn đã cố gắng tạo nhiều danh mục phụ?
Khoa TruongDinh

Tôi không chắc ý của bạn là gì. Hiện tại tôi chỉ đang cố gắng thêm một lớp "kiểm tra" vào menu con ulđể xác nhận rằng tôi đã vượt qua thành công lớp Topmenu.
MichaelRushton

Làm thế nào bạn có thể làm điều này? Hướng dẫn của tôi có thể giúp bạn?
Khoa TruongDinh

Tôi làm theo hướng dẫn của bạn là tốt nhất tôi hiểu nhưng nó không hoạt động. Mô-đun Topmenu tùy chỉnh của tôi bị bỏ qua và hành vi mặc định đang được sử dụng.
MichaelRushton

Vào cuối tuần, tôi sẽ kiểm tra lại và đưa ra giải pháp cho bạn.
Khoa TruongDinh

Câu trả lời:


20

Khối ghi đè:

Tạo mô-đun của riêng bạn trong app/codethư mục.
Chúng ta có thể sử dụng preferenceđể ghi đè lớp trong Magento 2.

ứng dụng / mã / Nhà cung cấp / Mô-đun / etc / di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="Magento\Theme\Block\Html\Topmenu" type="Vendor\Module\Block\Html\Topmenu" />
</config>

ứng dụng / mã / Nhà cung cấp / Mô-đun / Khối / Html / Topmenu.php

<?php

namespace Vendor\Module\Block\Html;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{

    protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
    {

    }

}

Giải pháp tạm thời:
Hiện tại, dường như các bước trên không thể ghi đè hoàn toàn khối. Chúng ta cần tạo chủ đề tùy chỉnh mới. Và sau đó, tạo default.xmltệp:

ứng dụng / thiết kế / frontend / Nhà cung cấp / Chủ đề / Magento_Theme / layout / default.xml

<?xml version="1.0"?>

<page layout="3columns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="default_head_blocks"/>
    <referenceBlock name="catalog.topnav" class="Vendor\Module\Block\Html\Topmenu" template="Magento_Theme::html/topmenu.phtml"/>
</page>

Đây có thể là một lỗi Magento: Chúng ta có bị buộc phải viết lại một mẫu trong Magento2 khi viết lại một khối không?

[BIÊN TẬP]

1) Chúng tôi có thể đặt mẫu:

ứng dụng / mã / Nhà cung cấp / Mô-đun / Khối / Html / Topmenu.php

public function setTemplate($template)
{
    return parent::setTemplate('Vendor_Module::custom-menu.phtml');
}

2) Đặt mẫu qua Xml:

Ví dụ:

ứng dụng / mã / Nhà cung cấp / Mô-đun / chế độ xem / frontend / layout / checkout_cart_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.cart">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Magento_Checkout::cart.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

Nhớ tạo registration.phpmodule.xml.

Chúng tôi tạo mô-đun mới vì chúng tôi ghi đè lên lớp Magento. Khi chúng ta muốn ghi đè bất kỳ lớp nào, chúng ta phải tạo mô-đun mới .

Các thuộc chủ đề tùy chỉnh app/design/frontendbao gồm:
--layout
--templates
--js
--html mẫu (Knockout mẫu)
--less, css
--etc ...

Đọc thêm ở đâyở đây .

Tự động tải tiêu chuẩn và quy ước đặt tên:

Đối với [Namespace][Module], chúng ta nên đọc thêm ở đây:

http://www.php-fig.org/psr/psr-0/
http://www.php-fig.org/psr/psr-4/
http://alanstorm.com/magento_2_autoloader_and_group_generation


Cảm ơn, nhưng tôi không thể làm việc này. Tôi đã chỉnh sửa nỗ lực của mình thành câu hỏi của tôi để bạn có thể thấy tôi chắc chắn đã sai ở đâu.
MichaelRushton

Mẫu gì?
MichaelRushton

Tôi cập nhật câu trả lời của tôi. Có vẻ như có một lỗi Magento. Chúng ta cần tạo chủ đề tùy chỉnh mới. Và sau đó, tạo bố cục để thiết lập lại lớp.
Khoa TruongDinh

Vâng, điều đó đã làm việc. Cảm ơn rât nhiều. Một ngày lãng phí cho một lỗi ...
MichaelRushton

Tôi phải ghi đè tệp khối trong custom_account_create.xml nằm trong tệp theme.xml tùy chỉnh của tôi nằm trong thư mục Magento_Customer. Tôi phải thay đổi magento_theme hoặc magento_customer ?? Tôi không thể ghi đè lên khối. tốt hơn để di chuyển Magento 2.1.3 ??
vijay b

3

Đối với ghi đè danh mục sản phẩm Khối sản phẩm.

1) Tạo tệp di.xml trong Thư mụcVendor/Module/etc

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Model\Product" type="Vendor\Module\Model\Rewrite\Catalog\Product" />
</config>

2) Tạo tập tin Chặn List SẢNt.php trong Thư mụcVendor/Module/Block/Rewrite/Product

<?php
namespace Vendor\Module\Block\Rewrite\Product;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    public function _getProductCollection()
    {
        // Do your code here
    }
}

Đối với mô hình danh mục sản phẩm ghi đè.

1) Thêm tùy chọn trong di.xml trước

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Model\Product" type="Vendor\Module\Model\Rewrite\Catalog\Product" />
</config> 

2) Tạo tệp Model.php trong Thư mụcVendor/Module/Model/Rewrite/Catalog

<?php
namespace Vendor\Module\Model\Rewrite\Catalog;

class Product extends \Magento\Catalog\Model\Product
{
    public function isSalable()
    {
        // Do your code here

        return parent::isSalable();
    }

}

Đối với bộ điều khiển ghi đè

1) Thêm tùy chọn trong di.xml

2) Tạo tập tin Trình điều khiển View.php tạiVendor/Module/Controller/Rewrite/Product

class View extends \Magento\Catalog\Controller\Product\View
{
    public function execute()
    {
        // Do your stuff here
        return parent::execute();
    }
}

Bạn có thể ghi đè lên khối, mô hình và bộ điều khiển khác bằng cách sử dụng phương pháp tương tự này.


Có vẻ như ghi đè của lớp \ Magento \ Catalog \ Block \ Product \ ListSản phẩm không hoạt động (trong Magento 2.2 Có thể?), Tham khảo liên kết - github.com/magento/magento2/issues/13152
Aniruddha A Deshpande

0

Để ghi đè lớp, bạn phải tạo một mô-đun nơi bạn có thể thêm tệp etc/di.xmlBlock/Html/Topmenu.phptệp (mã ở trên do bạn đăng)

trong đó Namespace là tên nhà cung cấp của bạn và Module là tên mô-đun của bạn. Ví dụ: Magento là Không gian tên và Chủ đề là Tên mô-đun.

Để biết thêm thông tin về cách tạo mô-đun, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure


0

Vì lỗi này: https://github.com/magento/magento2/issues/3724 bạn không thể chỉ ưu tiên các lớp chặn.

1) (Ưu tiên) Thay vào đó, sử dụng Plugin cho lớp đó và thay đổi những gì bạn cần.http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

2) Hoặc nếu bạn thực sự muốn thực hiện theo cách ưu tiên thì bạn cũng cần sao chép mẫu từ lõi sang mô-đun / chủ đề của mình và cập nhật bằng xml để sử dụng mẫu đó thay vào đó, sau đó nó sẽ bắt đầu hoạt động một cách kỳ diệu ..

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.