6

我正在尝试在组件的 RTF 字段中使用锚按钮,并出现意外行为。使用设计视图中的 Chrome 浏览器,我突出显示/选择<h2>My Heading</h2>要用作锚点的标题(即),然后按锚点按钮并输入锚点名称(即 my_place)。

这导致以下代码显示在我的源选项卡中:

<a name="my_place" id="myplace"/><h2>My Heading</h2>

由于自关闭<a/>标记,这会导致在浏览器中显示 HTML 时出现渲染问题。

我本来希望以下三个 HTML 片段之一被插入到 HTML 源代码中:

<a name="my_place" id="myplace"><h2>My Heading</h2></a>

或者

<h2><a name="my_place" id="myplace">My Heading</a></h2>

或者

<a name="my_place" id="myplace"><a><h2>My Heading</h2>

有没有其他人经历过这个?或知道实现我所期望的方法(无需手动编辑 HTML)。或者这是产品当前版本中的错误。

4

4 回答 4

6

谢谢克里斯,我已经编辑了您的解决方案以满足我的要求,因此希望将来与此问题的任何人分享。

注意:这会移动锚点内的文本并删除锚点外的文本。修复了仅包含文本而非 html 的锚点。即我的解决方案修复了这个标签:

<p><a name="anchor1" id="anchor1"></a>Anchor text</p>

<p><a name="anchor1" id="anchor1">Anchor text</a></p>

但不是这个:

<p><a name="anchor1" id="anchor1"></a><h1>Anchor text</h1></p>

这是我的xsl。希望它可以帮助您提供一个基础,我相信您可以轻松更新它以查找以下标签(我的解决方案不需要这个)。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" method="html" cdata-section-elements="script"/>
    <xsl:template match="/ | node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>

    <!-- fixes Tridion bug when using interface button to insert anchor in rich text field -->
    <!-- gets all empty anchor tags with an id and takes any following text and copies it inside anchor -->
    <xsl:template match="a[(@id) and (count(node()) = 0)]">
       <xsl:copy>
            <xsl:for-each select="@*">
                <xsl:attribute name="{name(.)}">
                    <xsl:value-of select="."/>                    
                </xsl:attribute>
            </xsl:for-each>
            <xsl:value-of select="normalize-space(following-sibling::text())"/>
        </xsl:copy>
    </xsl:template>
    <!-- delete any text after an empty anchor (template above has already copied this text inside the anchor) -->
    <xsl:template match="text()[preceding-sibling::a[(@id) and (count(node()) = 0)]]" ></xsl:template>
</xsl:stylesheet>

这是我的测试 XML

<?xml version ="1.0"?>
<?xml-stylesheet type="text/xsl" href="tridionhtmlfield.xsl"?>
<html>
    <head></head>
    <body>
        <p><a id="anchorlink" name="anchorlink" title="Anchor link" href="#Anchor">Anchor link</a>Some text after</p>
        <p><a name="broken-with-html-name" id="broken-with-html-id"></a><h1>Anchor - broken with html</h1></p>
        <p><a name="broken-text-only-name" id="broken-text-only-id"></a>Anchor - broken text only</p>
        <p><a name="broken-notext-name" id="broken-notext-id"></a></p>
        <p><a name="correct-name" id="correct-id">Anchor - correctly rendered</a> Some text after</p>
    </body>
</html>

改造后:

<html>
    <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
    <body>
        <p><a id="anchorlink" name="anchorlink" title="Anchor link" href="#Anchor">Anchor link</a>Some text after</p>
        <p><a name="broken-with-html-name" id="broken-with-html-id"></a><h1>Anchor - broken with html</h1></p>
        <p><a name="broken-text-only-name" id="broken-text-only-id">Anchor - broken text only</a></p>
        <p><a name="broken-notext-name" id="broken-notext-id"></a></p>
        <p><a name="correct-name" id="correct-id">Anchor - correctly rendered</a> Some text after</p>
    </body>
</html>

希望这可以帮助

于 2012-08-15T16:39:18.317 回答
6

附件是我的示例 XSLT 模板:

<template match="a[(@name) and (count(node()) = 0)]">
    <copy>
        <apply-templates select="@*"/>
        <xhtml:span xmlns:xhtml="http://www.w3.org/1999/xhtml" class="hidden"> </xhtml:span>
    </copy>
</template>

这增加了比严格需要的多一点,但处理了由于内容交付端的 XML 操作而导致的其他一些问题。

本质上,它将所有空a标签与一个name属性匹配,并在它们之间添加一些东西以阻止它们自动关闭。在我们的例子中,我们使用 XSLT 对所有 XML 进行后期处理,因此我们面临着空标签一直被关闭的挑战。所以作为一个肮脏的黑客,我们现在span在空标签之间插入一个隐藏标签来防止这个问题。

于 2012-05-10T19:48:17.120 回答
4

对我来说,这看起来像是一个错误,克里斯。我刚刚在 Chrome、Firefox 和 IE 上确认了这一点。应该忽略当前的文本选择是完全违反直觉的。(从好的方面来说,一旦你在源选项卡中手动修复它,一切似乎都表现得很完美。)

我建议您向 Tridion 报告此问题,或许可以通过更改模板或过滤 XSLT 来解决此问题。

于 2012-05-10T16:48:27.860 回答
2

这是 Tridion 中的一个错误。我建议(并已在我们的特定安装中实施)的一种解决方法是执行以下操作:

  1. 编辑 FormatAreaStyles.css 文件(可在 Tridion CMS 程序文件中找到)以及网站使用的 CSS 文件,以包含如下类:

.hiddenanchor { width:1px; height: 1px; display: block; text-indent:-50000px; }

  1. 发布您的 CSS 文件(使用新类),以便正确格式化您的锚点。
  2. 然后在构建锚点的组件中,您必须:

    一个。在您的组件(您希望目标所在的位置)中键入一个单词或一系列单词,

    湾。选择该文本,并将锚标记应用于它,

    C。然后将您创建的新类 (.hiddenanchor) 应用到锚点。

最后,您的“隐形”锚将如下所示:

<a name="anchorname" id="anchorname" class="hiddenanchor">Anchor Name</a>

这是一个粗略的解决方法——完全承认。但它有效。在下一个 DOM 对象关闭之前,您不会得到超链接/下划线样式。

作为对 CSS 的解释,从技术上讲,锚点必须在 DOM 中可见,它才能工作并且可以被锚点链接访问。所以“显示:无”将不起作用。除了采用文本缩进方法之外,您也可以将文本绝对或固定在屏幕之外。

于 2012-07-12T18:59:37.810 回答