v2.1에서 블록을 재정의하는 방법


14

Magento 2.1의 Topmenu 블록을 재정의하려고하는데 그렇게 할 수있는 가이드를 찾을 수 없습니다. 여기와 다른 곳에서 찾은 모든 것은 다른 폴더 구조를 사용하는 것처럼 보이는 버전 2.0에만 적용되는 것 같거나 부분적 코드 예제 만 가지고있어서 올바른 컨텍스트를 이미 알고있을 것으로 기대합니다.

사용자 정의 테마의 현재 폴더 구조는 app/design/frontend/Vendor/theme_name입니다. 이 안에는 등록, 테마 및 작곡가 파일뿐만 아니라 다양한 모듈의 폴더 (예 : Magento_Theme및)가 Magento_Search있습니다.

나는이와 함께 시작하는 데 필요한 이해하는 것과 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="[Namespace]\[Module]\Block\Html\Topmenu" />
</config>

또한 다음 단계는 Block/Html/Topmenu.php아래와 같은 파일 을 추가하는 것입니다 (위 소스에서 다시 편집 함).

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

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

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

  }

}

그러나 [Namespace]및에 사용해야 할 [Module]파일 또는 이러한 파일을 어디에 배치 해야하는지 명확하지 않습니다 . 공급 업체와 테마 이름을 사용하고에 etcBlock폴더 app/design/frontend/Vendor/theme_name를 배치하고에 배치하고 app/design/frontend/Vendor/theme_name/Magento_Theme네임 스페이스를Vendor\theme_name\Magento_Theme\Block\Html 아무런 영향을 미치지 않습니다.

누구든지 버전 2.1에서 Topmenu 블록을 무시하고 다른 블록을 유추하기 위해해야 ​​할 일을 정확하게 설명하는 데 도움이된다면 대단히 감사하겠습니다.

추가

Khoa TruongDinh 의 답변을 시도했지만 아무런 영향을 미치지 않았습니다. 다음 파일을 사용했습니다.

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__
);

나는 다음의 내용을 삭제했습니다 pub/static/frontend, var/generation그리고 var/view_preprocessed, 그리고 젠토 캐시를 플러시. 하위 메뉴에는 의도 된 "테스트"클래스가 추가되지 않았습니다.

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

여러 하위 카테고리를 만들려고하십니까?
Khoa TruongDinh

무슨 말인지 잘 모르겠습니다. 지금은 하위 메뉴 ul에 "test"클래스를 추가 하여 Topmenu 클래스를 성공적으로 재정의했음을 확인하려고합니다.
MichaelRushton

어떻게 할 수 있습니까? 내 가이드가 당신을 도울 수 있습니까?
Khoa TruongDinh

나는 내가 이해 한대로 당신의 지시를 따랐지만 작동하지 않았습니다. 내 사용자 정의 Topmenu 모듈이 무시되고 기본 동작이 사용되고 있습니다.
MichaelRushton

주말에 다시 확인하고 해결책을 알려 드리겠습니다.
Khoa TruongDinh

답변:


20

무시 블록 :

app/code폴더 아래에 자신의 모듈을 만듭니다 . Magento 2에서 클래스를 재정의하는 데
사용할 수 있습니다 preference.

앱 / 코드 / 공급 업체 / 모듈 /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>

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

<?php

namespace Vendor\Module\Block\Html;

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

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

    }

}

임시 해결책 :
현재 위의 단계는 블록을 완전히 무시할 수없는 것으로 보입니다. 새로운 커스텀 테마를 만들어야합니다. 그런 다음 default.xml파일을 작성 하십시오.

app / design / frontend / Vendor / Theme / 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>

Magento 버그 일 수 있습니다 . 블록을 다시 작성할 때 Magento2에서 템플릿을 다시 작성해야합니까?

[편집하다]

1) 템플릿을 설정할 수 있습니다.

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

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

2) Xml을 통한 템플릿 설정 :

예를 들면 다음과 같습니다.

app / code / Vendor / Module / view / 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>

만들 기억 registration.php하고 module.xml.

Magento 클래스를 재정의하기 때문에 새 모듈을 만듭니다. 클래스를 재정의하려면 새 모듈을 만들어야합니다 .

아래의 사용자 정의 테마 app/design/frontend에는 다음이 포함됩니다.
--layout
--templates
--js
--html 템플릿 (녹아웃 템플릿) --less
, css
--etc ...

여기여기에 더 읽기 .

자동 로딩 표준 및 명명 규칙 :

들어 [Namespace][Module], 우리는 더 많은 여기 읽어야합니다 :

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


고마워요, 그러나 나는 이것을 작동시키지 못했습니다. 내 질문에 대한 내 시도를 편집하여 필연적으로 잘못 된 부분을 볼 수 있습니다.
MichaelRushton

템플릿은 무엇입니까?
MichaelRushton

내 답변을 업데이트했습니다. 마 젠토 버그가있는 것 같습니다. 새로운 커스텀 테마를 만들어야합니다. 그런 다음 레이아웃을 만들어 클래스를 다시 설정하십시오.
Khoa TruongDinh

그렇습니다. 대단히 감사합니다. 버그에 하루 낭비 ...
MichaelRushton

내 사용자 정의 theme.xml 파일에있는 custom_account_create.xml의 블록 파일을 Magento_Customer 폴더에 있습니다. default.xml magento_theme 또는 magento_customer를 변경해야합니까? 나는 block.을 무시할 수 없습니다. Magento 2.1.3을 옮기는 것이 더 좋습니까 ??
vijay b

3

카탈로그 제품 ListProduct 블록을 대체합니다.

1) 폴더에 di.xml 파일 생성Vendor/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) 폴더에 ListProduct.php 블록 파일 생성Vendor/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
    }
}

카탈로그 제품 모델을 대체합니다.

1) 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\Catalog\Model\Product" type="Vendor\Module\Model\Rewrite\Catalog\Product" />
</config> 

2) 폴더에 Product.php 모델 파일 생성Vendor/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();
    }

}

컨트롤러 재정의

1) di.xml에 환경 설정 추가

2) View.php Controller 파일을 생성하십시오Vendor/Module/Controller/Rewrite/Product

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

이 같은 접근 방식을 사용하여 다른 블록, 모델 및 컨트롤러를 무시할 수 있습니다.


클래스 \ Magento \ Catalog \ Block \ Product \ ListProduct의 재정의가 작동하지 않는 것 같습니다 (Magento 2.2에서?) 링크 참조 -github.com/magento/magento2/issues/13152
Aniruddha A Deshpande

0

클래스를 무시하려면 당신은 당신이를 추가 할 수있는 모듈을 만들어야 etc/di.xml하고Block/Html/Topmenu.php 파일을 합니다 (코드가 게시 한 위)

여기서 네임 스페이스 는 공급 업체 이름이고 모듈 은 모듈 이름입니다. 예 : Magento는 네임 스페이스이고 Theme는 모듈 이름입니다.

모듈을 만드는 방법에 대한 자세한 내용은 http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure


0

이 버그로 인해 https://github.com/magento/magento2/issues/3724 블록 클래스를 선호 할 수는 없습니다.

1) (권장) 대신 작동하는 것은 해당 클래스에 플러그인 을 사용하고 필요한 것을 변경하는 것입니다.http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

2) 또는 기본 설정 방법을 실제로 원한다면 코어에서 모듈 / 테마로 템플릿을 복사하고 해당 템플릿을 대신 사용하도록 xml로 업데이트해야 마술처럼 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.