كيفية التحقق من وجود الكتلة (بناءً على نوعها)
-
11-12-2019 - |
سؤال
هذا يحيرني حقا!!
لقد وصلت إلى موقف حيث أحتاج إلى إنشاء كتلة جديدة (core/template
block) برمجيًا، في حالة وجود كتلة CMS في تخطيط الصفحة.بشكل عام، حسب علمي، هناك حلان لهذا الغرض.
1.إضافة كتلة من خلال التخطيط
في معظم الحالات، ستكون هذه هي أفضل فكرة للقيام بهذه المهمة.يمكننا إضافة كتلة إلى الصفحة إذا كان مقبض التخطيط المناسب متاحًا.لكن لسوء الحظ، في حالتي، ليس لدي أي مقبض تخطيط خاص بكتلة ثابتة متاح (بالنسبة لصفحات cms، نعلم أن هناك cms_page
مقبض).لذلك لا أستطيع الاعتماد على هذه الطريقة
2.استخدم مراقبًا
الطريقة الثانية هي الاستماع إلى مراقب مناسب.مرة أخرى، لا يمكنني العثور على مراقب قائم على كتلة ثابتة يتم تشغيله أثناء وقت تحميل التخطيط/الكتلة.ومع ذلك، هناك بعض المراقبين العامين الذين يمكنني الاعتماد عليهم.أظن controller_action_layout_generate_blocks_before
يمكن استخدامها في حالتي.لكن هنا أواجه مشكلتي الحقيقية
مشكلتي الحقيقية
لذلك عندما أستخدم controller_action_layout_generate_blocks_before
في حالتي، المشكلة هي أنه لا يمكنني استرداد الكتل بناءً على نوعها.يمكنني تصفية الكتل بناءً على name
, ، ولكن ليس على أساسهم type
.أي
$observer->getEvent()->getLayout()->getBlock('block_name'); //this work; Used name
$observer->getEvent()->getLayout()->getBlock('cms/block'); //this wont; use type
لا أستطيع الاعتماد على الأسماء في الواقع. لأنني أريد الحصول على كل شيء cms/block
اكتب الكتل وأضف قالبًا جديدًا بعد التحقق من بعض خصائصها المخصصة التي قمت بتعيينها باستخدام الكتلة الثابتة
فكيف يمكنني الحصول على كل شيء cms/block
من خلال مراقب؟هل من الممكن حتى.يرجى مشاركة أفكارك.
المحلول
استخدم هذا:
<core_block_abstract_prepare_layout_before>
<observers>
<ssd_test>
<class>ssd_test/observer</class>
<method>generateBlocks</method>
<type>singleton</type>
</ssd_test>
</observers>
</core_block_abstract_prepare_layout_before>
مراقب:
public function generateBlocks($observer)
{
/**
* @var $block Mage_Core_Block_Abstract
*/
$block = $observer->getEvent()->getBlock();
if ($block->getType() == 'cms/block') {
//do something
}
}
تشير إلى protected function _toHtml()
التابع Mage_Cms_Block_Block
إذا كنت تريد أن تفعل بعض التغييرات.
تحديث (حل آخر)
<controller_action_layout_generate_blocks_after>
<observers>
<ssd_test>
<class>ssd_test/observer</class>
<method>generateBlocks</method>
<type>singleton</type>
</ssd_test>
</observers>
</controller_action_layout_generate_blocks_after>
المراقب.php:
public function generateBlocks($observer)
{
/**
* @var $l Mage_Core_Model_Layout
*/
$l = $observer->getEvent()->getLayout();
$newBlock = $l->createBlock(
'Mage_Core_Block_Template',
'new_block_name_here',
array('template' => 'some_template.phtml')
);
foreach ($l->getAllBlocks() as $block) {
if ($block->getType() == 'cms/block') {
$l->getBlock('some_block_name')->append($newBlock);
}
}
}
نصائح أخرى
لا يمكنك مجرد الاستماع إلى هذا الحدث core_block_abstract_to_html_before
ثم تحقق من نوع الكتلة في الحدث وقم بتحديث القالب بناءً على ذلك؟شيء مثل ما يلي يجب أن يفعل ذلك.
$block = $observer->getBlock();
if ($block instanceof Mage_Cms_Block_Block) {
// Make your changes here
}
سيعمل هذا مع جميع الكتل، ولكن إذا كنت تعلم أن هذا يحدث فقط في حالات قليلة، فأنا أقترح تغيير القالب عبر تخطيط XML.
أو إذا كنت تريد إلحاق شيء ما بكتلة ما ولكن اتركها كما هي، فيمكنك استخدام core_block_abstract_to_html_after
احصل على ال transport
مرت على الحدث.ثم احصل على مجموعة html مقابل هذا وألحق ما تحتاجه.مرة أخرى، يمنحك هذا الحدث الحظر حتى تتمكن من تحديد التعليمات البرمجية الخاصة بك بكل بساطة Mage_Cms_Block_Block
$block = $observer->getBlock();
if ($block instanceof Mage_Cms_Block_Block) {
$transport = $observer->getTransport();
$html = $transport->getHtml();
$html .= 'We need to append something here';
$transport->setHtml($html);
}
بقدر ما أتذكر، يمكنك الحصول على جميع الكتل كمجموعة أو مصفوفة من التخطيط ثم تكرار التحقق من نوعها باستخدام عامل التشغيل "مثيل".