Syndicating LDN in Luminis III.2

0
No votes yet

I would like to be able to syndicate LDN into Luminis so everytime I login, I'll see the headlines and can keep up with what is going on here. However, I seem to be having some trouble. The XML/RSS link on the right side of the page brings up the RSS feed (v .92) This seems perfect, yet when I publish this in the portal as a .9X RSS channel, it fails to render.

I get:
Error message: Problem parsing http://ldn.messiah.edu/index.php?q=node/feed: java.lang.NullPointerException

Outer exception:
org.jasig.portal.GeneralRenderingException at org.jasig.portal.channels.CGenericXSLT.renderXML(CGenericXSLT.java:297) at org.jasig.portal.MultithreadedChannelAdapter.renderXML(MultithreadedChannelAdapter.java:75) at campuspipeline.uportal.ScheduledChannelRenderer$ScheduledWorker.run(ScheduledChannelRenderer.java:609) at com.pipeline.uportal.ChannelRendererTaskInterceptor$1.run(ChannelRendererTaskInterceptor.java:114) at java.security.AccessController.doPrivileged(Native Method) at com.pipeline.uportal.ChannelRendererTaskInterceptor.run(ChannelRendererTaskInterceptor.java:100) at com.sct.pipeline.concurrent.PooledExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Thread.java:479)

Has anyone had any success making this work?

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I've made some modifications

I've made some modifications to rss-0_9xwebbrowser.xsl for an error I was getting with other feeds.  However even with my modified stylesheet I get the same error as you.  I'll be interested in any answer you get on this one.

John

RSS XSL

are you just modifying the file in...


$CP_ROOT/webapps/luminis/stylesheets/org/jasig/portal/channels/CGenericXSLT/RSS/

...? Because that isn't the one that is being used. You will have to modify the XSL file in...

$CP_WEBINF/lib/uPortal.jar

That is the active one.

RSS XSL

Yep, I was modifying the jar file.

Doesn't Validate

The feed doesn't seem to validate as RSS 0.92. It did using feedvalidator.org, but not using RSSOwl, Cooktop nor Real Simple. You could write a XSL that will transform it correctly then just use a XML Transformation channel instead. I've done something similar for RSS 2.0 feeds.

XML feed

A bit ironic that the LDN content can't be syndicated as a Luminis channel, eh ?

I'll see what I can do.  It would be useful if it will work.  I have access to the code that renders the XML for the feed, and looking at the feed, it looks like the headers are incorrect, and giving the Parse error.

I'll let you know what I find out.

 -Jon

Luminis LDN Channel

It works now, only it doesn't appreciate html code.  There's code throughout.  Wonder why. Anyone know ?  I'm sure it has to do with the way Drupal is rendering it. I'll have to dig a little deeper.  Seems to work nice though other than that.

Just make sure you have enough timeout, and set the RSS Version to 0.9x (RSS format)

You can create a Recent BLOG postings channel with this -

http://ldn.messiah.edu/index.php?q=blog/feed

 -Jon

Close enough for me

Cool!  That's close enough for me, It's just me an a couple others around here who are subscribing to it. 

Think we could use our collective pressure to get SCT to make the next Luminis version support RSS 2.0?  Maybe Uportal already does and we need not worry.

RSS 2.0 support in Luminis

I just tested uPortal v2.4.1 and it has 2.0 support. We are working on upgrading Luminis to the latest version of uPortal so 2.0 support will be coming as found in the uPortal codebase. However, when I published this feed in 2.4.1 it redered but didn't properly render the nested html elements. They just came through escaped and hence appeared in the browser.

HTML in RSS

Your post got me thinking, is HTML really intended to go in RSS?  Was this feature in fact added in 2.0?

It turns out (according to the O'Reilly Book Content Syndication with RSS page 33) that HTML should not be in the description element of RSS of any version.  This is apparently a topic of great debate both practically and philosophically.

If there is HTML in the description, suddenly there has to be some complex login in the reader to handle it.  Additionally, as indexable metadata, it becomes more cumbersome when HTML is included.

My suggestion both to uPortal and SCT might be to just strip any HTML that appears in the description.  Suddenly the problem of nested HTML is less complex, and you are still within the standard.  Just my opinion...

RSS / HTML

You make an excellent point, an RSS feed is XML.  XML is the separation of structured data _from_ its design and layout elements.  That's why there is .XLS. 

I'm sure you could probably run a nice regsub to strip html elements on the feed when it comes in.  If you're caching it, that makes it even easier, or one would think.

Hmmm, how to strip html tags from the midst of an XML RSS feed.  You sure don't want to remove everything between the left and right < >s  that would be a mess <BIGGRIN>

 -Jon

HTML in RSS descriptions

Some RSS versions do allow the use of HTML in them and the stock RSS stylesheets in uPortal/Luminis do not handle them. I solved this by adding the following to the stylesheet files located at $CP_ROOT/webapps/luminis/stylesheets/org/jasig/portal/channels/CGenericXSLT/RSS and updating the uportal.jar file. It is not perfect but does handle <p>, <b>, and <i>.

<xsl:variable name="pTagStart">&lt;p&gt;</xsl:variable>
<xsl:variable name="pTagEnd">&lt;/p&gt;</xsl:variable>
<xsl:variable name="bTagStart">&lt;b&gt;</xsl:variable>
<xsl:variable name="bTagEnd">&lt;/b&gt;</xsl:variable>
<xsl:variable name="iTagStart">&lt;i&gt;</xsl:variable>
<xsl:variable name="iTagEnd">&lt;/i&gt;</xsl:variable>

 <xsl:template name="fixDesc">
    <xsl:param name="aString"/>

    <!-- Locate position of the first open/close tags in the string -->
    <xsl:variable name="tagPositions">
      <tag tag="pStart">
        <xsl:attribute name="pos">
          <xsl:choose>
            <xsl:when test="string-length(substring-before($aString, $pTagStart)) &gt; 0 or starts-with($aString, $pTagStart)">
              <xsl:value-of select="string-length(substring-before($aString, $pTagStart))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>-1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </tag>
      <tag tag="pEnd">
        <xsl:attribute name="pos">
          <xsl:choose>
            <xsl:when test="string-length(substring-before($aString, $pTagEnd)) &gt; 0 or starts-with($aString, $pTagEnd)">
              <xsl:value-of select="string-length(substring-before($aString, $pTagEnd))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>-1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </tag>

      <tag tag="bStart">
        <xsl:attribute name="pos">
          <xsl:choose>
            <xsl:when test="string-length(substring-before($aString, $bTagStart)) &gt; 0 or starts-with($aString, $bTagStart)">
              <xsl:value-of select="string-length(substring-before($aString, $bTagStart))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>-1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </tag>
      <tag tag="bEnd">
        <xsl:attribute name="pos">
          <xsl:choose>
            <xsl:when test="string-length(substring-before($aString, $bTagEnd)) &gt; 0 or starts-with($aString, $bTagEnd)">
              <xsl:value-of select="string-length(substring-before($aString, $bTagEnd))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>-1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </tag>

      <tag tag="iStart">
        <xsl:attribute name="pos">
          <xsl:choose>
            <xsl:when test="string-length(substring-before($aString, $iTagStart)) &gt; 0 or starts-with($aString, $iTagStart)">
              <xsl:value-of select="string-length(substring-before($aString, $iTagStart))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>-1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </tag>
      <tag tag="iEnd">
        <xsl:attribute name="pos">
          <xsl:choose>
            <xsl:when test="string-length(substring-before($aString, $iTagEnd)) &gt; 0 or starts-with($aString, $iTagEnd)">
              <xsl:value-of select="string-length(substring-before($aString, $iTagEnd))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>-1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </tag>
    </xsl:variable>

    <xsl:variable name="firstTag">
      <xsl:apply-templates select="xalan:nodeset($tagPositions)/tag[@pos!=-1]">
        <xsl:sort data-type="number" select="@pos"/>
      </xsl:apply-templates>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="$firstTag = 'pStart'">
        <xsl:value-of select="substring-before($aString, $pTagStart)"/>
        <!--<p>-->
        <xsl:call-template name="fixDesc">
          <xsl:with-param name="aString" select="substring-after($aString, $pTagStart)"/>
        </xsl:call-template>
        <!--</p>-->
        <xsl:call-template name="fixDesc">
          <xsl:with-param name="aString" select="substring-after($aString, $pTagEnd)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$firstTag = 'pEnd'">
        <xsl:value-of select="substring-before($aString, $pTagEnd)"/>
      </xsl:when>

      <xsl:when test="$firstTag = 'bStart'">
        <xsl:value-of select="substring-before($aString, $bTagStart)"/>
        <b>
          <xsl:call-template name="fixDesc">
            <xsl:with-param name="aString" select="substring-after($aString, $bTagStart)"/>
          </xsl:call-template>
        </b>
        <xsl:call-template name="fixDesc">
          <xsl:with-param name="aString" select="substring-after($aString, $bTagEnd)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$firstTag = 'bEnd'">
        <xsl:value-of select="substring-before($aString, $bTagEnd)"/>
      </xsl:when>

      <xsl:when test="$firstTag = 'iStart'">
        <xsl:value-of select="substring-before($aString, $iTagStart)"/>
        <i>
          <xsl:call-template name="fixDesc">
            <xsl:with-param name="aString" select="substring-after($aString, $iTagStart)"/>
          </xsl:call-template>
        </i>
        <xsl:call-template name="fixDesc">
          <xsl:with-param name="aString" select="substring-after($aString, $iTagEnd)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$firstTag = 'iEnd'">
        <xsl:value-of select="substring-before($aString, $iTagEnd)"/>
      </xsl:when>

      <xsl:otherwise>
        <xsl:value-of select="$aString"/>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>

  <xsl:template match="tag">
    <xsl:if test="position() = 1">
      <xsl:value-of select="@tag"/>
    </xsl:if>
  </xsl:template>

Now for any description element you do:

<xsl:call-template name="fixDesc">
  <xsl:with-param name="aString">
    <xsl:copy-of select="rss10:description"/>
  </xsl:with-param>
</xsl:call-template>

opps

You need to add

xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan"

to the xsl:stylesheet block otherwise you will get an error.

BTW an easier method that works when you use xalan via the command line is:

<xsl:copy-of select="description" disable-output-escaping="yes"/>

However if you try this within Luminis you will get this error

XSLT.getTemplates():"disable-output-escaping" attribute is not allowed on the xsl:copy-of element

Anyone know how we can get around that?