Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Johan Roug 97 posts 153 karma points
    Jun 10, 2010 @ 13:58
    Johan Roug
    0

    TruncateString

    Hi

    I use this code, to Truncate the string

    <xsl:variable name="body" select="$node/data[@alias = 'Body']" />
    <xsl:value-of select="umbraco.library:TruncateString(umbraco.library:StripHtml($body) ,100, '...')" disable-output-escaping="yes" />

     

    however. Because entries can contain special charachters like æ, ø, å., these are converted to fx "&aring;" But the HTML is Truncated before the characthers are converted. This means that"&aring;" might be cut in the middle, and the correct charachter is not displayed on the webpage

     

     

    Thanks

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Jun 10, 2010 @ 14:16
    Douglas Robar
    0

    The problem isn't with the StripHtml() or the TruncateString() function. Rather, the richtext editor has already converted special characters for you, such as &aring;

    You'll need a more detailed bit of code to be sure you don't truncate your string in the middle of an entity tag because (as you've seen) the simple approach is too simplistic for the actual data.

    cheers,
    doug.

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jun 10, 2010 @ 15:11
    Matt Brailsford
    0

    I'd probably look at making your own extension method to do the truncation on whole words instead, this way, even if they are encoded, it will never split in the middle of a word.

    Have a look here for a couple of example methods you could use:

    http://stackoverflow.com/questions/1613896/truncate-string-on-whole-words-in-net-c

    Matt

  • Johan Roug 97 posts 153 karma points
    Jun 10, 2010 @ 15:15
    Johan Roug
    0

    thanks for the help. I'm still stuck though :)

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jun 10, 2010 @ 15:59
    Matt Brailsford
    0

    lol, what exactly are you stuck on?

    Matt

  • Johan Roug 97 posts 153 karma points
    Jun 10, 2010 @ 16:14
    Johan Roug
    0

    I need a hint for the XSLT, cause I won't be making extensions

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jun 11, 2010 @ 09:48
    Matt Brailsford
    1

    Guess if you wanted to do it all in XSLT you could just split the string on a space, and pull back the first 10 words. I've not tested it, but this should work.

    <xsl:variable name="body" select="umbraco.library:StripHtml($node/data[@alias = 'Body'])" />
    <xsl:variable name="bodyParts" select="umbraco.library:Split($body, ' ')" />
    <xsl:variable name="bodySummary">
        <xsl:for-each select="$bodyParts/value">
            <xsl:if test="position() &lt; 10">
                <xsl:if test="position() &gt; 1"><xsl:text> </xsl:text></xsl:if>
         <xsl:value-of select="." />
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    <xsl:value-of select="concat($bodySummary, '...')" />

    Matt

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jun 11, 2010 @ 09:59
    Matt Brailsford
    0

    Or this might be better (again, i've not tested it)

    <xsl:variable name="body" select="umbraco.library:TruncateString(umbraco.library:StripHtml($node/data[@alias = 'Body']), 100, '')" />
    <xsl:variable name="bodySummary">
        <xsl:choose>
            <xsl:when test="contains($body, ' ')">
                <xsl:value-of select="substring($body, 0, umbraco.library:LastIndexOf($body, ' '))" />
            </xsl:choose>
            <xsl:otherwise>
                <xsl:value-of select="$body" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:value-of select="concat($bodySummary, '...')" />

    Matt

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jun 11, 2010 @ 10:00
    Matt Brailsford
    0

    The last one should crop at 100 characters, and then work it's way back to the last space chracter, so you don't split a word.

    Matt

  • Johan Roug 97 posts 153 karma points
    Jun 11, 2010 @ 10:41
    Johan Roug
    0

    It works to some degree. But now every special charahter is just html code.

    There is also a minor mistake in your code. Your when tag ends with a choose tag. Just a typo :)

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jun 11, 2010 @ 11:10
    Matt Brailsford
    0

    Ooops, thats what I get for typing it in notepad =)

    You should just need the disable-output-escaping="yes" putting back on the end then

    <xsl:value-of select="concat($bodySummary, '...')" disable-output-escaping="yes" />

    Matt

  • Johan Roug 97 posts 153 karma points
    Jun 11, 2010 @ 11:22
    Johan Roug
    0

    wow. this works just perfect. Thanks a lot. Here is the finnehsed code

     

                        <xsl:variable name="body" select="umbraco.library:TruncateString(umbraco.library:StripHtml($node/data[@alias = 'Body']), 100, '')" />

     

                        <xsl:variable name="bodySummary">

                            <xsl:choose>

                                <xsl:when test="contains($body, ' ')">

                                    <xsl:value-of select="substring($body, 0, umbraco.library:LastIndexOf($body, ' '))" />

                                </xsl:when>

                            <xsl:otherwise>

                                <xsl:value-of select="$body" />

                            </xsl:otherwise>

                            </xsl:choose>

                        </xsl:variable>

                        <xsl:value-of select="concat($bodySummary, '...')" disable-output-escaping="yes" />

     

  • Streety 358 posts 568 karma points
    Sep 22, 2010 @ 14:56
    Streety
    0

    Hello, am getting the same thing. Not sure how to apply your fix and am getting errors.

     

    Heres Code:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [
        <!ENTITY nbsp "&#x00A0;">
    ]>
    <xsl:stylesheet
     version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:msxml="urn:schemas-microsoft-com:xslt"
     xmlns:umbraco.library="urn:umbraco.library"
     exclude-result-prefixes="msxml umbraco.library">


        <xsl:output method="xml" omit-xml-declaration="yes"/>

        <xsl:param name="currentPage"/>
        <xsl:param name="MaxNoChars" select="100" />

        <xsl:variable name="noOfItems" select="2" />

        <xsl:template match="/">
           
                <xsl:for-each select="$currentPage/ancestor-or-self::node//node [@nodeTypeAlias ='9News']/node">
                    <xsl:sort select="@Name" order="descending"/>

                    <!-- Position() <= $noOfItems -->
                    <xsl:if test="position()&lt;= $noOfItems">
                          
                                 <h4><img src="../images/newspaper.png" alt="News" class="left iconpic" />
                              <a href="{umbraco.library:NiceUrl(@id)}">
        <!--  <xsl:value-of select="umbraco.library:FormatDateTime(@createDate, ' dd MMM yyyy ')"/> - -->
        <xsl:value-of select="@nodeName" />
                              </a>
                          </h4>
                         
                              <p><!-- TODO: strip HTML & truncate -->


                              <xsl:value-of disable-output-escaping="yes" select="umbraco.library:TruncateString(umbraco.library:StripHtml(data [@alias = 'bodyText']), $MaxNoChars, '...')" />
                          

     


        <a href="{umbraco.library:NiceUrl(@id)}">more</a>
        </p>
                       
                      
                    </xsl:if>
                   
                </xsl:for-each>
          

        </xsl:template>

    </xsl:stylesheet>

  • Streety 358 posts 568 karma points
    Sep 23, 2010 @ 11:52
    Streety
    0

    Solved this myself and disn't realise.

     

    disable-output-escaping="yes"

     

    Doh!

  • syn-rg 282 posts 425 karma points
    Mar 01, 2011 @ 04:13
    syn-rg
    0

    I've tried this myself but I'm not getting the HTML to strip in.

    The property alias I have is mainContent however I can't get it working.

    Can someone help me out, I'm guessing it's just correcting the body and bodySummary code with I have, but I can't figure it out. Am I missing something?

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxml="urn:schemas-microsoft-com:xslt"
      xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:PS.XSLTsearch="urn:PS.XSLTsearch"
      exclude-result-prefixes="msxml
    umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes
    Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings
    Exslt.ExsltSets PS.XSLTsearch "
    >

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>
    <xsl:variable name="body" select="umbraco.library:TruncateString(umbraco.library:StripHtml(./mainContent), 100, '')" />
    <xsl:template match="/">

    <!-- The fun starts here -->

      <div id="sector_list_container">
        <ul>
          <xsl:for-each select="$currentPage/* [@isDoc and string(umbracoNaviHide) != '1']">
          <li>
            <div class="info">
              <h1>
                <a href="{umbraco.library:NiceUrl(@id)}" title="{@nodeName}">
                  <xsl:value-of select="@nodeName"/>
                </a>
              </h1>
              <p>
                <a href="{umbraco.library:NiceUrl(@id)}" title="{@nodeName}">
                  <xsl:variable name="bodySummary">
                    <xsl:choose>
                      <xsl:when test="contains($body, ' ')">
                        <xsl:value-of select="substring($body, 0, umbraco.library:LastIndexOf($body, ' '))" />
                      </xsl:when>
                      <xsl:otherwise>
                        <xsl:value-of select="$body" />
                      </xsl:otherwise>
                    </xsl:choose>
                  </xsl:variable>
                  <xsl:value-of select="concat($bodySummary, '...')" disable-output-escaping="yes" />&nbsp;more</a>
              </p>         
            </div>
            <!-- Display the thumbnail -->
            <xsl:if test="sectorImage != ''">
              <a href="{umbraco.library:NiceUrl(@id)}" title="{@nodeName}">
                <img src="{concat(substring-before(sectorImage,'.'), '_thumb_225.jpg')}"/>
              </a>
            </xsl:if>   
          </li>
          </xsl:for-each>
        </ul>
      </div>


    </xsl:template>

    </xsl:stylesheet>
  • Kim Andersen 1447 posts 2196 karma points MVP
    Mar 01, 2011 @ 07:53
    Kim Andersen
    0

    Hi JV

    If you are trying to test on the current node that's being iterated through, you must have the declaration of the body variable inside your for-each loop. This line:

    <xsl:variable name="body" select="umbraco.library:TruncateString(umbraco.library:StripHtml(./mainContent), 100, '')" />

    Otherwise the XSLT doesn't know where to find the mainContent when you are not using $currentPage.

    /Kim A

  • syn-rg 282 posts 425 karma points
    Mar 01, 2011 @ 23:31
    syn-rg
    0

    Thanks Kim,

    However I'm still not getting any of the HTML from the child node. All I'm getting is "... more" which means it's missing everything before the last part of the links code (...more).

Please Sign in or register to post replies

Write your reply to:

Draft