4

我是 Magento 的新手,在探索系统时我发现的一件尴尬的事情是将生成的 (X)HTML 页面中的给定元素与创建它的块的名称联系起来。我知道系统->配置->模板路径提示。但是,它非常难看,有时会改变页面上元素的布局,并且不会显示所有块(我认为它仅涵盖模板块)。

我尝试过的一种方法是修改toHtml()Mage_Core_Block_Abstract 中的方法以在内容之前和之后添加空元素,例如。

<blockStart xmlns="http://some/url" name="the_block_name"/>
<!-- the block's contents -->
<blockEnd/>

(可能有一种方法可以在不修改核心文件的情况下做到这一点,但我现在并不介意这种方法,因为它仅供我自己使用。欢迎任何想法。)

这些元素在文档中为我提供了足够的信息,让我可以在.nextUntil()浏览器端使用 jQuery 的功能data-magento-blockname为 blockStart 和 blockEnd 元素之间的元素添加属性。然后,我可以使用这些属性在任何给定时间显示一个工具提示,其中包含指向指针下内容的完整块名称“路径”。

这种方法的问题在于,尽管 Magento 生成具有严格 DOCTYPE 的 XHTML,但将 Content-Type 设置为“text/html”是硬编码的(参见app/code/core/Mage/Core/Model/App.php第 1246 行)。这意味着浏览器将 XML 解释为 HTML“标签汤”,导致发生奇怪的事情 - 我的许多标签完全消失,出现在错误的位置或没有立即关闭,因此它们包含其他内容。此外,并非文档中的所有 HTML 元素都显示在 DOM 中。

我尝试修改 App.php 以将 Content-Type 更改为 application/xhtml+xml,这确实使我的机制能够成功运行。但是,它有一些严重的缺点:

  1. 我不得不禁用不能生成有效 XHTML 的加载项,尤其是 Commerce Bug。Commerce Bug 的丢失非常糟糕,因为我真的希望在我的加载项运行时访问它的页面并打包 XML 查看功能。
  2. Magento 中包含的大部分 javascript 都使用了 document.write(),它不适用于 XHTML,因此我得到了 javascript 异常,并且可能某些功能不起作用。

是否有人知道我的方法对这些问题的任何解决方案,或者知道将输出中的 HTML 元素链接到生成它们的 Magento 块的任何更简单的方法?

4

2 回答 2

2

使用模板路径提示时,有时您需要检查元素,然后通过在 ChromeDevTools 或 Firebug 中查看列出的关联模板文件(它将是具有一堆内联样式的父元素)。

我也经常使用 grep 来查找内容。只需导航到您认为应该查找的最高文件夹(以免遍历数千个不相关的文件夹/文件)。

因此,如果您知道块名称,并且想查找哪些模板文件使用该块,您可以转到 /app/design/frontend/base/default/layout 并执行以下操作:

grep "catalog/category" -r -l .

并且您应该能够获得一些正在加载该块的文件名,然后找到它们的声明节点并查看正在加载的模板文件。

echo get_class($this)

也可以有所帮助。

于 2012-10-05T00:28:54.490 回答
1

更新它最终花了一段时间,但最后我给你 BlockSpy:http ://omnicognate.wordpress.com/2012/11/13/blockspy-my-first-magento-extension/


更新没有太多时间来处理它,但我现在已经完成了这项工作的服务器端部分。通过在事件处理程序中添加我的 blockStart/blockEnd 标记,core_block_abstract_to_html_after我设法在不修改任何核心文件的情况下做到了这一点,并且通过将它们放在注释中,我让它们不受干扰地通过 HTMLTidy。SAX 解析器位正在工作。只需要做一些 javascript 客户端,这应该很简单——想法是以 CSS XRAY 书签 (http://westciv.com/xray/) 的样式做一些事情。

我将链接到一篇关于它如何工作的文章,并在完成后更新并接受这个答案 - 当然,如果其他人之前没有提出更好的解决方案。


我想我正在接近解决这个问题。看来问题真的归结为三件事:

  1. Magento 并不能真正生成可靠有效的 XHTML。例如,对于 Javascript 使用 CDATA 部分存在一些不一致。我遇到了一些无效页面,毫无疑问还有更多。
  2. 页面的生成以纯文本方式完成。由于服务器操作的是字符串,而不是 DOM,因此在服务器端可靠地插入标记并不容易。此外,AFAIK 不能保证块的toHtml()方法总是会产生整个元素的集合。例如,没有什么可以阻止您(我认为)拥有一个生成文本并将其嵌入到父块中的属性值中的块,或者在父块中打开 XHTML 元素并在子块中关闭它(尽管那样会冷酷无情)。
  3. 将 Content-Type 切换为 XHTML,即使服务器被说服生成正确有效的标记,也会完全破坏站点上的 javascript,而且我不准备通过并更新它以使用 XHTML。

我认为以下方法可以解决这些问题:

  1. 在服务器端使用PHP::Tidy以强制服务器生成有效的 XHTML。我已经通过tidy_parse_string()controller_front_send_response_before处理程序中运行来尝试这个,它似乎工作。
  2. 与其在客户端处理 Block 类插入的 blockStart/blockEnd 标记,不如在服务器端使用 SAX XML 解析器在发送响应之前对其进行处理。我可以遍历标记之间的子字符串,将每个子字符串传递给 SAX 解析器(并忽略标记)。这应该允许我维护状态并构建输出 XML 字符串以响应 SAX 解析器生成的事件。然后我可以在服务器端安全地(如果缓慢)插入 data- *属性。
  3. 将 Content-Type 保留为 text/html。这将允许 javascript 工作,并且 data- *属性将根据需要在客户端被忽略。

这有点痛苦,但它似乎应该适用于我的所有扩展,避免破坏 javascript 并避免对块产生什么样的输出做出任何假设。我只尝试了第一步-一旦我对棘手的部分有所了解就会更新:-)

于 2012-10-05T17:13:19.687 回答