How to Easily display Digg posts via XSLT using Digg Api

As we know, Digg become very popular last time, so why not use it for our purposes? I decided to investigate Digg a little and learn how possible to draw Digg posts at my own website. And I make own unique method. Hope you will like it.
Reading http://digg.com/api/docs/1.0/groups/ I find necessary ways to get posts XML results. Just check story.getPopular method. Yes, this is usual to use different reparse methods in PHP, but lets learn something new like XSLT (Extensible Stylesheet Language Transformations).

[sociallocker]

download in package

[/sociallocker]


Step 1. PHP

Ok, here are all used PHP files:

index.php

This file will generate list of Digg stories. As you can see – I already put several samples ($sMethod values) for different methods. So you can try any method. All code commented, so I hope it will easy to understand it.

01 <?php
06 $sXmlSrc = getDiggStoriesXml($sMethod);
07 // Load the XML source
08 $xml new DOMDocument;
09 $xml->loadXML($sXmlSrc);
10 // Load XSLT
11 $xsl new DOMDocument;
12 $xsl->load('xslt/digg.xslt');
13 // Configure the transformer
14 $proc new XSLTProcessor;
15 $proc->importStyleSheet($xsl); // attach the xsl rules
16 echo '<link media="all" href="css/styles.css" type="text/css" rel="stylesheet">';
17 echo $proc->transformToXML($xml);
18 // this function get digg information using caching (not more 1 times per minute)
19 function getDiggStoriesXml($sUrl 'http://services.digg.com/1.0/endpoint?method=story.getPopular') {
20     // used cache folder
21     $sCacheFolder 'cache/';
22     // formatting cache name
23     $sFilename date("YmdHi").'.xml';
24     if (! file_exists($sCacheFolder.$sFilename)) {
25         //grab the XML and save it to a temp XML file
26         $ch = curl_init($sUrl);
27         $fp fopen($sCacheFolder.$sFilename"w");
28         curl_setopt($ch, CURLOPT_FILE, $fp);
29         curl_setopt($ch, CURLOPT_HEADER, 0);
30         curl_setopt($ch, CURLOPT_HTTPHEADER, Array("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.15) Gecko/20080623 Firefox/2.0.0.15") ); // makes our request look like it was made by Firefox
31         curl_exec($ch);
32         curl_close($ch);
33         fclose($fp);
34     }
35     return file_get_contents($sCacheFolder.$sFilename);
36 }
37 ?>

Step 2. CSS

Here are used CSS styles.

css/styles.css

001 .news-summary, .news-full, .news-full-confirm {
002 background:none repeat scroll 0 0 #F3F3F3;
003 border:1px solid #CCCCCC;
004 clear:left;
005 margin:10px;
006 min-height:55px;
007 padding:10px;
008 position:relative;
009 }
010 .news-body {
011 padding-left60px;
012 }
013 .news-body a.body {
014 text-decorationnone;
015 padding4px;
016 margin-4px 0 -4px -4px;
017 color#555;
018 positionrelative;
019 z-index2;
020 }
021 .news-summary .news-body em {
022 color#999;
023 white-spacenowrap;
024 }
025 .news-body em a {
026 color#777;
027 text-decorationnone;
028 border-bottom1px solid #ddd;
029 }
030 .news-body em a:hover {
031 color#000;
032 }
033 .news-digg {
034 positionabsolute;
035 top0.8em;
036 left0;
037 text-aligncenter;
038 font-size85%;
039 margin0 0 0 3px;
040 padding0;
041 list-stylenone;
042 backgroundurl(../img/shade-news.gif) no-repeat;
043 }
044 .digg-count a, .digg-count span  {
045 displayblock;
046 padding10px 0 4px 0;
047 text-decorationnone;
048 width50px;
049 min-height40px;
050 color#93883F;
051 text-aligncenter;
052 }
053 .news-summary .digg-count strong {
054 font-size160%;
055 font-weightnormal;
056 letter-spacing-1px;
057 line-height1;
058 displayblock;
059 color#736926;
060 }
061 .digg-count img {
062 positionabsolute;
063 top0;
064 left0;
065 bordernone;
066 }
067 .digg-count a:hover, .digg-count a:hover strong {
068 color#998D43;
069 }
070 .news-body h3 {
071 margin2px 0 0 0;
072 font-size115%;
073 letter-spacing-0.01em;
074 font-weightbold;
075 line-height1.1;
076 }
077 .news-body p {
078 margin0.2em 0 0.1em 0;
079 line-height1.3;
080 }
081 .news-body em {
082 font-stylenormal;
083 font-size85%;
084 color#666;
085 }
086 span.news-img {
087 displayblock;
088 width80px;
089 height80px;
090 background#ddecee url(../img/v-default.gif);
091 border1px solid #a5c2e3;
092 positionabsolute;
093 left60px;
094 top8px;
095 }
096 .img-summary span.news-img {
097 background#ddecee url(../img/i-default.gif);
098 }
099 span.news-img em {
100 displayblock;
101 width80px;
102 height80px;
103 text-indent-2000em;
104 backgroundurl(../img/v-frame-simple.png);
105 }
106 .img-summary span.news-img em {
107 backgroundurl(../img/i-frame-simple.png);
108 }
109 .v .news-body {
110 margin-left:0;
111 min-height:70px;
112 padding-left:152px;
113 padding-right:0;
114 }
115 .comments {
116 background:transparent url(../img/i-cmts.gif) no-repeat scroll 0 4px;
117 word-spacing:-0.1em;
118 color:#578CCA;
119 padding:4px 6px 4px 18px;
120 font-size:85%;
121 }

Step 3. XSLT

I hope this is most interesting part of my story, used XSLT rules:

xslt/digg.xslt

01 <?xml version="1.0" encoding="ISO-8859-1"?>
02 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
03     <!-- <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/> -->
04     <xsl:template match="stories">
05         <html>
06             <body>
07                 <xsl:for-each select="story">
08                     <div>
09                         <xsl:attribute name="class">
10                             <xsl:choose>
11                                 <xsl:when test="thumbnail">news-summary v img-summary</xsl:when>
12                                 <xsl:otherwise>news-summary</xsl:otherwise>
13                             </xsl:choose>
14                         </xsl:attribute>
15                         <div class="news-body">
16                             <h3>
17                                 <a target="_blank">
18                                     <xsl:attribute name="title"><xsl:value-of select="@link"/></xsl:attribute>
19                                     <xsl:attribute name="href">
20                                         <xsl:for-each select="shorturl">
21                                             <xsl:value-of select="@short_url"/>
22                                         </xsl:for-each>
23                                     </xsl:attribute>
24                                     <xsl:value-of select="title"/>
25                                 <xsl:for-each select="thumbnail">
26                                     <span style="background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat;" class="news-img">
27                                     <xsl:attribute name="style">background: transparent url(<xsl:choose>
28                                             <xsl:when test="string-length(@src) > 0">
29                                                 <xsl:value-of select="@src" />
30                                               </xsl:when>
31                                         </xsl:choose>) repeat scroll 0% 0%;</xsl:attribute>
32                                     <em>view!</em></span>
33                                 </xsl:for-each>
34                                 </a>
35                             </h3>
36                             <div>
37                                 <p>
38                                 <a class="body" style="color:#555;">
39                                 <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
40                                 <xsl:value-of select="description"/>
41                                 </a>
42                                 <em>(Submitted by <a>
43                                 <xsl:for-each select="user">
44                                     <xsl:attribute name="href">
45                                         http://digg.com/users/<xsl:choose>
46                                             <xsl:when test="string-length(@name) > 0">
47                                                 <xsl:value-of select="@name" />
48                                               </xsl:when>
49                                         </xsl:choose>
50                                     </xsl:attribute>
51                                     <xsl:value-of select="@name" />
52                                 </xsl:for-each>
53                                 </a>)</em>
54                                 </p>
55                             </div>
56                                 <div class="news-details">
57                                         <span class="tool comments">
58                                     <xsl:attribute name="title"><xsl:value-of select="title"/></xsl:attribute>
59                                     <xsl:value-of select="@comments"/> Comments</span>
60                             </div>
61                         </div>
62                         <ul class="news-digg">
63                                 <li class="digg-count">
64                                         <a>
65                                 <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
66                                 <xsl:attribute name="title"><xsl:value-of select="title"/></xsl:attribute>
67                                         <strong><xsl:value-of select="@diggs"/></strong> diggs</a>
68                             </li>
69                         </ul>
70                     </div>
71                 </xsl:for-each>
72                 <xsl:comment>Copyright © AndrewP</xsl:comment>
73             </body>
74         </html>
75     </xsl:template>
76 </xsl:stylesheet>

Step 4. Images

Also we need several images for our project:

    i-cmts.gif
    i-default.gif
    i-frame-simple.png
    shade-news.gif

Step 5. Few important things

After reading http://digg.com/api/docs/concepts I found ‘Be Polite, Please!’, so I decode not request Digg api any time when user call it, and I made way using cache system. I started caching results. I created ‘cache’ folder with permission to write (you should create ‘cache’ folder too).
After I put .htaccess file in it with next text:
Options -Indexes

And now check index.php:
$sFilename = date(“YmdHi”).’.xml’;
So I using current year-month-day-hour-minute digits to generate cache filename. Hope you understand my idea 🙂


Conclusion

Today I told you how to display digg posts at your own website via XSLT transformations. Hope all my code easy to understand and comfortable to use. You can use this material to create own scripts into your startups. Good luck!