Solution: Creating custom rss feeds using the layout/set module view

This article which describes in detail using the layout/set module view in various ways.

Example Settings

These are the example settings of an average layout.ini.append.php

[podcast]
PageLayout=podcast_rss_pagelayout.tpl
ContentType=application/rss+xml
# Related issue, http://issues.ez.no/12677
# If you remove this line, URLs that are built using url_alias_list will have the following prepended, '/layout/set/json/'.
UseAccessPass=false
UseFullUrl=true

[podcast_episode]
PageLayout=podcast_episode_pagelayout.tpl
ContentType=text/html
# Related issue, http://issues.ez.no/12677
UseAccessPass=false
UseFullUrl=true

[discussions]
PageLayout=discussions_pagelayout.tpl
ContentType=application/rss+xml

[author]
PageLayout=author_rss_pagelayout.tpl
ContentType=application/rss+xml
# ContentType=text/xml

[comments]
PageLayout=comment_rss_pagelayout.tpl
ContentType=application/rss+xml
# ContentType=text/xml

[article_statistics.csv]
PageLayout=article_statistics_pagelayout.tpl
ContentType=text/csv
# ContentType=text/txt

Templates

Example template overrides for layout/set view.

Author Article RSS Feed

Example uri, '/layout/set/author?user=938'


{set-block scope=root variable=cache_ttl}0{/set-block}
{def $user_id=ezhttp( 'user', 'get' )}
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://example.com/rss/feed/user/{$user_id}" rel="self" type="application/rss+xml"/>
    <title>Example User Feed</title>
    <link>http://example.com</link>
    <description>A feed of the articles being started at example.com!</description>
    <language>en-US</language>
    <image>
      <url>http://example.com/var/ezwebin_site/storage/images/media/images/example_logo_rss.png</url>
      <title>example BETA User Feed</title>
      <link>http://example.com</link>
    </image>
{* ezhttp( 'user', 'get' )}  |-- <b>{$view_parameters.user}</b> {$view_parameters|attribute(show,1) *}

{if ezhttp_hasvariable( 'user', 'get' )}
{def $topics=fetch( 'content', 'list',
     hash( 'parent_node_id', 42,
           'limit',           30,
           'depth',            3,
           'class_filter_type',  'include',
           'class_filter_array', array( 'article','comment' ),
           'attribute_filter', array( array( 'owner',
                                        '=',
                                        $user_id ) ),
           'sort_by', array( 'published', false() )
     ) )}
{foreach $topics as $t}
    <item>
      <title>{if $t.object.owner.data_map.pen_name.has_content}{$t.object.owner.data_map.pen_name.content}{else}{$t.data_map.author.data_text}{/if}{if $t.object.class_identifier|eq('article')} : {$t.name|trim|htmlentities}{else} on {$t.parent.name|trim|htmlentities}{/if}</title>
      <author>{$t.object.owner.data_map.user_account.content.email} ({if $t.object.owner.data_map.pen_name.has_content}{$t.object.owner.data_map.pen_name.content}{else}{$t.data_map.author.data_text}{/if})</author>
      <link>http://example.com/{$t.url_alias}</link>
      <guid>http://example.com/{$t.url_alias}</guid>
      <description><![CDATA[{$t.data_map.body.content.output.output_text}]]></description>
      <pubDate>{$t.object.published|datetime('custom', '%D, %d %M %Y %H:%i:%s PDT')}</pubDate>{*
      <pubDate>Sat, 04 Jul 2010 13:54:12 GMT</pubDate> *}
    </item>
{/foreach}{/if}

  </channel>
</rss>

Article RSS Feed

Example uri, '/layout/set/articles'

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://example.com/rss/feed/articles" rel="self" type="application/rss+xml"/>    <title>example BETA article Feed</title>
    <link>http://example.com</link>
    <description>A feed of the articles from example.com</description>
    <language>en-US</language>
    <image>
      <url>http://example.com/var/ezwebin_site/storage/images/media/images/example-block-logo_rss.png</u
rl>
      <title>Example article Feed</title>
      <link>http://example.com</link>
    </image>
{def $topics=fetch( 'content', 'list',
     hash( 'parent_node_id', 77,
           'limit',           30,           'sort_by', array( 'published', false() )
     ) )}{foreach $topics as $t}
    <item>
      <title>{if $t.object.owner.data_map.pen_name.has_content}{$t.object.owner.data_map.pen_name.content}{else}{$t.data_map.author.data_text}{/if}: {$t.name|trim|was
h}</title>
      <author>[email protected] ({if $t.object.owner.data_map.pen_name.has_content}{$t.object.owner.data_map.pen_name.content}{else}{$t.data_map.author.data_text}{/if
})</author>
      <link>http://example.com/{$t.url_alias}</link>
      <guid>http://example.com/{$t.url_alias}</guid>
      <description><![CDATA[{$t.data_map.body.content.output.output_text}]]></description>
      <pubDate>{$t.object.published|datetime('custom', '%D, %d %M %Y %H:%i:%s PDT')}</pubDate>{*
      <pubDate>Sat, 04 Jul 2010 13:54:12 GMT</pubDate> *}
    </item>
{/foreach}

  </channel>
</rss>

Podcast RSS Feed

Example uri, '/layout/set/podcast'

{def $podcast_node_id=4200
     $max_episodes=50
     $podcast=fetch( 'content', 'node', hash( 'node_id', $podcast_node_id ) )
     $episodes=fetch( 'content', 'list', hash( 'parent_node_id', $podcast_node_id,
                                               'limit', $max_episodes,
                                               'class_filter_type', 'include',
                                               'class_filter_array', array( 'podcast_episode' ),
                                               'sort_by', array( 'published', false() ) ) )
     $podcastDescription='Example.com: The home of ...'
     $podcastItunesSubtitle='Example subtitle'
     $podcastItunesSummary='Example summary'
     $podcastItunesKeywords='Example, keywords'
     $podcastItunesCategory='News &amp; Opinion'
     $podcastImageUrl=concat('http://',ezsys('hostname'),'/extension/example/design/ezwebin/images/podcast/blocklogo144.jpg')
     $podcastItunesImageUrl=concat('http://',ezsys('hostname'),'/extension/example/design/ezwebin/images/podcast/ituneslogo.jpg')
     $podcastTitle=$podcast.data_map.title.content|trim|wash
     $siteUrl='http://example.com'
     $podcastUrl=concat($siteUrl,'/rss/feed/podcast')
     $podcastPageUrl=concat($siteUrl,'/podcast')
     $podcastItunesEmail='[email protected]'
     $audioFileUrl=''
     $audioFileLength=''
     $episodeDatamap=''
}<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
  <channel>
    <title>{$podcastTitle}</title>
    <link>{$siteUrl}</link>
    <description>{$podcastDescription}</description>
    <language>en-US</language>

    <copyright>(C) example.com {currentdate()|datetime( 'custom', '%Y' )}</copyright>
    <image>
      <url>{$podcastImageUrl}</url>
      <title>{$podcastTitle}</title>
      <link>{$siteUrl}</link>
      <width>144</width>
      <height>144</height>
    </image>
    <atom:link href="{$podcastUrl}" rel="self" type="application/rss+xml"/>
    <category>{$podcastItunesCategory}</category>
    <itunes:image href="{$podcastItunesImageUrl}" />    <itunes:author>example.com</itunes:author>
    <itunes:subtitle>{$podcastItunesSubtitle}</itunes:subtitle>
    <itunes:summary>{$podcastItunesSummary}</itunes:summary>
    <itunes:keywords>{$podcastItunesKeywords}</itunes:keywords>
    <itunes:explicit>no</itunes:explicit>
    <itunes:owner>
      <itunes:name>example.com</itunes:name>
      <itunes:email>{$podcastItunesEmail}</itunes:email>
    </itunes:owner>
    <itunes:block>no</itunes:block>
    <itunes:category text="{$podcastItunesCategory}"/>
    <pubDate>{if $episodes[0]}{if $episodes[0].data_map.published.has_content}{$episodes[0].data_map.published.content.timestamp|datetime('custom', '%D, %d %M %Y %H:%
i:%s -0700')}{else}{$episodes[0].object.published|datetime('custom', '%D, %d %M %Y %H:%i:%s -0700')}{/if}{/if}</pubDate>
    <lastBuildDate>{currentdate()|datetime('custom', '%D, %d %M %Y %H:%i:%s -0700')}</lastBuildDate>
{foreach $episodes as $episode}
{set $episodeDatamap=$episode.data_map
     $audioFileUrl=$episodeDatamap.audio.content
     $audioFileLength=$episodeDatamap.audio_length.content
}
    <item>
      <title>{$episode.name|trim|wash}</title>
{if $episodeDatamap.audio.has_content}

      <link>{$audioFileUrl}</link>
{else}

      <link>{$podcastPageUrl}</link>
{/if}

      <description>{$episodeDatamap.description.content|trim|wash}</description>
      <pubDate>{if $episodeDatamap.published.has_content}{$episodeDatamap.published.content.timestamp|datetime('custom', '%D, %d %M %Y %H:%i:%s -0700')}{else}{$episode.object.published|datetime('custom', '%D, %d %M %Y %H:%i:%s -0700')}{/if}</pubDate>
{if $episodeDatamap.audio.has_content}

      <enclosure url="{$audioFileUrl}" length="{$audioFileLength}" type="audio/mpeg"/>
      <guid isPermaLink="false">{$audioFileUrl}</guid>
{/if}
      <category>{$episodeDatamap.category.content|trim|wash}</category>
      <itunes:author>example.com</itunes:author>
      <itunes:subtitle>{$episodeDatamap.subtitle.content|trim|wash}</itunes:subtitle>
      <itunes:summary>{$episodeDatamap.description.content|trim|wash}</itunes:summary>
      <itunes:keywords>{$episodeDatamap.keywords.content.keyword_string|trim|wash}</itunes:keywords>
      <itunes:explicit>{if $episodeDatamap.explicit.content}yes{else}no{/if}</itunes:explicit>
      <itunes:duration>{$episodeDatamap.duration.content|trim}</itunes:duration>
    </item>
{/foreach}
  </channel>
</rss>

Comment RSS Feed

Example uri, '/layout/set/comment'

{set-block scope=root variable=cache_ttl}0{/set-block}
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://example.com/rss/feed/comments" rel="self" type="application/rss+xml"/>
    <title>Example Comment Feed</title>
    <link>http://example.com</link>
    <description>A feed of the comments from example.com.</description>
    <language>en-US</language>
    <image>
      <url>http://example.com/var/ezwebin_site/storage/images/media/images/example-block-logo-rss.png</url>
      <title>example BETA Comment Feed</title>
      <link>http://example.com</link>
    </image>
{def $topics=fetch( 'content', 'list',
     hash( 'parent_node_id', 77,
           'limit',           30,           'depth',            3,
           'class_filter_type',  'include',           'class_filter_array', array( 'comment' ),
           'sort_by', array( 'published', false() )
     ) )}
{if $topics|count|gt(0)}
{foreach $topics as $t}
    <item>
      <title>{if $t.object.owner.data_map.pen_name.has_content}{$t.object.owner.data_map.pen_name.content}{else}{$t.data_map.author.data_text}{/if}{if $t.object.class
_identifier|eq('article')} : {$t.name|trim|htmlentities}{else} on {$t.parent.name|trim|htmlentities}{/if}</title>
      <author>{$t.object.owner.data_map.user_account.content.email} ({if $t.object.owner.data_map.pen_name.has_content}{$t.object.owner.data_map.pen_name.content}{else}{$t.data_map.author.data_text}{/if})</author>
      <link>http://example.com/{$t.parent.url_alias}/(comment)/{$t.node_id}#comment-{$t.node_id}</link>
      <guid>http://example.com/{$t.parent.url_alias}/(comment)/{$t.node_id}#comment-{$t.node_id}</guid>
      <description><![CDATA[{$t.data_map.body.content.output.output_text}]]></description>
      <pubDate>{$t.object.published|datetime('custom', '%D, %d %M %Y %H:%i:%s PDT')}</pubDate>{*
      <pubDate>Sat, 04 Jul 2010 13:54:12 GMT</pubDate> *}
    </item>
{/foreach}{/if}

  </channel>
</rss>

Article Statistics CSV Export

Example uri, '/layout/set/article_statistics.csv?startDate=2010-07-14&endDate=2010-07-19'

{* Example: http://example.com/layout/set/article_statistics.csv?startDate=2010-07-14&endDate=2010-07-19 *}
{def $articles=false()
$commentCount=false()
$articleTitle=false()
$articleOwner=false()
$articleDate=false()
$articleTime=false()
$articleWordCount=false()
$articleFollowCount=false()
$articleShareCount=false()}

{if and( ezhttp_hasvariable( 'startDate', 'get' ), ezhttp_hasvariable( 'endDate', 'get' ) )}

{def $startDate=ezhttp( 'startDate', 'get' )|explode("-")
     $endDate=ezhttp( 'endDate', 'get' )|explode("-")}
{def $startDateTimestamp=maketime(0,0,0,$startDate.1,$startDate.2,$startDate.0)
     $endDateTimestamp=maketime(23,59,59,$endDate.1,$endDate.2,$endDate.0)}
{set $articles=fetch( 'content', 'list', hash(
     'parent_node_id', 77,
     'class_filter_type', 'include',
     'class_filter_array', array( 'article' ),
     'sort_by', array( 'published', false() ),
     'attribute_filter', array( array( 'published', '>=', $startDateTimestamp ),
                                array( 'published', '<', $endDateTimestamp ) )
 ) )}
{else}
{set $articles=fetch( 'content', 'list', hash(
     'parent_node_id', 77,
     'class_filter_type', 'include',
     'class_filter_array', array( 'article' ),
     'sort_by', array( 'published', false() ),
     'limit', 10000
 ) )}
{/if}"Date","Time","Title","Who","Words","Comments","Followers","Shared","Post or Comment","Url"

{foreach $articles as $con}{* article variables count etc. Counts the words in the body xml string *}{set
     $commentCount=fetch( 'content', 'tree_count', hash(
     'parent_node_id', $con.object.main_node_id,
     'class_filter_type', 'include',
     'class_filter_array', array( 'comment' ) ) )
     $articleTitle=$con.object.name|explode('"')|implode("")
     $articleOwner=$con.object.owner.name|explode('"')|implode("")
     $articleWordCount=$con.data_map.body.content.output.output_text|explode( '>' )|implode( '> ' )|strip_tags|simplify|explode( ' ' )|count
     $articleFollowCount=fetch( 'example', 'getfollowerscount', hash( 'id', $con.node_id ) )
     $articleShareCount=fetch( 'example', 'getsharecounts', hash( 'id', $con.node_id ) )
     $articleDate=$con.object.published|datetime( 'custom', '%d-%M' )
     $articleTime=$con.object.published|datetime( 'custom', '%h:%i:%s %A' )
}
"{$articleDate}",{$articleTime},"{$articleTitle}","{$articleOwner}",{$articleWordCount},{$commentCount},{$articleFollowCount},{$articleShareCount},"P","http://example.com/{$con.url_alias}"

{/foreach}

References