How Does Docs.Composite.Net pull in latest forum activities?

Topics: General
Aug 1, 2011 at 10:52 PM

Hi,

I was looking at the Developers tab of your main page, which is http://docs.composite.net/C1.aspx.  I noticed that bottom right has the "Latest forum activity" and you pull the latest posts into that cell.  How do you do that and are you using your C1 system for your site?  I'm trying to create a main page like yours to pull in 3 of the latest blog posts.  I'm hoping that C1 will let me do all of this.

Thank you so much.

Aug 1, 2011 at 10:54 PM
Edited Aug 1, 2011 at 10:57 PM

There is a RSS feed from CodePlex - we pull this into an XSLT Function by using the Composite.Xml.LoadUrl function and provide it with the path to the RSS feed - pretty simple stuff.

Aug 1, 2011 at 11:14 PM

Is there a sample as to how to do this somewhere in the documentation?

Aug 1, 2011 at 11:15 PM

Also, how can I pull in the latest 3 posts from a blog, for example?  Thank you

Aug 2, 2011 at 12:41 AM

Perhaps you can use this package right out of the box: http://docs.composite.net/Composite.Feeds.RssReader - if creates an XSLT Function called Composite.Feeds.RssReader you can tweak.

Alternative

Here is a small sample using the code we currently use to populate the CodePlex feed on our docs front page - it creates a function that takes a URL as parameter (expecting it to be a RSS feed) and then presents the top 3 results. Also there is a parameter for controlling how compact the teaser text should be.

Please note that the CodePlex RSS feed need some extra logic to prevent that a post that got multiple replies show up identical multiple times - the XSLT below works around this - you can probably simplify this if you want.

Our XSLT Function has 2 input parameters (create these on the Input Parameters tab):

  • Url
    Of type string, no default value (put in a test value for a RSS feed). Use http://compositec1.codeplex.com/project/feeds/rss?ProjectRSSFeed=codeplex%3a%2f%2fforum%2fcompositec1 for testing
  • CompactMode
    Of type Boolean, default value is 'True'

This is the function call markup used by the XSLT Function (what gets called from the Functions tab) is just a single function call, looking like this when XML serialized:

 

<f:functions xmlns:f="http://www.composite.net/ns/function/1.0">
  <f:function name="Composite.Xml.LoadUrl" localname="LoadUrl">
    <f:param name="Url">
      <f:function name="Composite.Utils.GetInputParameter">
        <f:param name="InputParameterName" value="Url" />
      </f:function>
    </f:param>
  </f:function>
</f:functions>

 

This is the XSLT template - you can probably simplify it, this is a direct copy of our specific layout:

 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:in="http://www.composite.net/ns/transformation/input/1.0"
  xmlns:lang="http://www.composite.net/ns/localization/1.0"
  xmlns:f="http://www.composite.net/ns/function/1.0"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:csharp="http://c1.composite.net/csharp"
  exclude-result-prefixes="xsl in lang f csharp">

  <xsl:param name="rss" select="/in:inputs/in:result[@name='LoadUrl']/rss/channel" />
  <xsl:key name="items" match="/in:inputs/in:result[@name='LoadUrl']/rss/channel/item" use="link" />  
  <xsl:variable name="TitleMaxLength">
    <xsl:choose>
      <xsl:when test="/in:inputs/in:param[@name='CompactMode']='true'">33</xsl:when>
      <xsl:otherwise>200</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="TextMaxLength">
    <xsl:choose>
      <xsl:when test="/in:inputs/in:param[@name='CompactMode']='true'">84</xsl:when>
      <xsl:otherwise>200</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  
  <xsl:template match="/">
    <html>
      <head />
      <body>
         <xsl:for-each select="$rss/item[generate-id()=generate-id(key('items',link)[1])][position()&lt;4]">
          <h4>&#9658;
            <a href="{link}">
              <xsl:variable name="topic">
                <xsl:choose>
                  <xsl:when test="string-length(title) &lt; $TitleMaxLength">
                    <xsl:value-of select="title" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="substring(title,0,$TitleMaxLength - 4)" />...
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text" select="$topic" />
                <xsl:with-param name="replace" select="'&amp;quot;'" />
                <xsl:with-param name="by" select="'&quot;'" />
              </xsl:call-template>
            </a>
          </h4>
          <p>
            <xsl:variable name="description">
              <xsl:apply-templates select="description" mode="striptag" />
            </xsl:variable>

            <xsl:variable name="content">
              <xsl:value-of select="csharp:HtmlDecode($description)" />
            </xsl:variable>



            <xsl:choose>
              <xsl:when test="string-length($content) &lt; $TextMaxLength">
                <xsl:value-of select="$content" />
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="substring($content,0,$TextMaxLength - 4)" />...
              </xsl:otherwise>
            </xsl:choose>
          </p>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="string-replace-all">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="by" />
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text,$replace)" />
        <xsl:value-of select="$by" />
        <xsl:call-template name="string-replace-all">
          <xsl:with-param name="text" select="substring-after($text,$replace)" />
          <xsl:with-param name="replace" select="$replace" />
          <xsl:with-param name="by" select="$by" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template mode="striptag" match="*">
    <xsl:param name="str" select="." />
    <xsl:choose>
      <xsl:when test="string-length(substring-after($str,'&lt;')) = 0">
        <xsl:value-of select="$str" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="substring-before($str,'&lt;')" />
        <xsl:if test="string-length(substring-after($str,'&gt;'))>0">
          <xsl:apply-templates select="." mode="striptag">
            <xsl:with-param name="str" select="substring-after($str,'&gt;')" />
          </xsl:apply-templates>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <msxsl:script implements-prefix="csharp" language="C#" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
    <msxsl:assembly name="System.Web"/>
    <msxsl:using namespace="System.Web"/>
    <![CDATA[
    public string HtmlDecode(string text)
    {
      return HttpUtility.HtmlDecode(text);
    }
  ]]>
  </msxsl:script>  
  
    
</xsl:stylesheet>

 

 

Aug 2, 2011 at 1:17 AM

Much appreciated! Thank you so much for your time.