Создание ссылок привязки в полях с расширенным текстом с помощью SDL Tridion 2011 SP1

Я пытаюсь использовать кнопку привязки в поле RTF компонента и получаю неожиданное поведение. Используя браузер Chrome в режиме конструктора, я выделяю / выбираю заголовок (т.е. <h2>My Heading</h2>) Я хочу использовать в качестве привязки, и нажмите кнопку привязки и введите имя привязки (то есть my_place).

Это приводит к тому, что следующий код отображается на моей вкладке источника:

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

Это вызывает проблемы рендеринга при отображении HTML в браузере из-за самозакрывающегося <a/> тег.

Я ожидал, что один из следующих трех фрагментов 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 ответа

Решение

Прилагается мой образец 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 атрибут, и добавить что-то между ними, чтобы они не закрывались самостоятельно. В нашем случае мы публикуем весь XML с помощью XSLT, поэтому у нас возникают проблемы с закрытием пустых тегов. Так что как грязный хак, мы сейчас вставляем скрытый span тег между пустыми тегами, чтобы предотвратить проблему.

Спасибо, Крис, я отредактировал твоё решение, чтобы соответствовать моим требованиям, поэтому хотел бы поделиться с кем-нибудь с этой проблемой в будущем.

Примечание. Это перемещает текст внутри якоря и удаляет текст снаружи. Исправляет якоря, которые должны были содержать только текст, но не 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>

Надеюсь это поможет

Это похоже на ошибку для меня Крис. Я только что подтвердил это на Chrome, Firefox и IE. Совершенно нелогично, что текущий выделенный текст следует игнорировать. (С другой стороны, после того, как вы исправите это вручную на вкладке источника, кажется, что все работает отлично.)

Я предлагаю вам сообщить об этом в Tridion и, возможно, обойти это, изменив свой шаблон или XSLT.

Это ошибка в Tridion. Один из обходных путей, который я предлагаю (и реализовал в нашей конкретной установке), заключается в следующем:

  1. Отредактируйте файл FormatAreaStyles.css (находится в программных файлах Tridion CMS), а также ваш CSS-файл, используемый веб-сайтом, для включения такого класса:

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

  1. Опубликуйте свой CSS-файл (с новым классом), чтобы он правильно форматировал ваши якоря.
  2. И затем в компоненте, где вы строите якоря, вам необходимо:

    а. введите слово или серию слов в свой компонент (где вы хотите, чтобы цель была),

    б. выделите этот текст и примените к нему тег привязки,

    с. затем примените новый класс, который вы создали (.hiddenanchor) к якору.

В конце ваш "невидимый" якорь будет выглядеть так:

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

Это грубый обходной путь - полностью признанный. Но это работает. Вы не получите стиль гиперссылки / подчеркивания до закрытия следующего объекта DOM.

В качестве объяснения CSS, якорь технически должен быть видим в DOM, чтобы он работал и был доступен по ссылке якоря. Так что "display: none" не будет работать. В качестве альтернативы подходу с отступом текста, вы также можете установить абсолютное или фиксированное положение текста за пределами экрана.

Другие вопросы по тегам