Get htmltmpl mostly working

This commit is contained in:
Sam Ruby 2006-08-29 15:19:35 -04:00
parent d17d509adc
commit 92eab64934
30 changed files with 544 additions and 46 deletions

View File

@ -64,17 +64,19 @@ def __init__():
# planet wide options
define_planet('name', "Unconfigured Planet")
define_planet('link', "Unconfigured Planet")
define_planet('link', '')
define_planet('cache_directory', "cache")
define_planet('log_level', "WARNING")
define_planet('feed_timeout', 20)
define_planet('date_format', "%B %d, %Y %I:%M %p")
define_planet('new_date_format', "%B %d, %Y")
define_planet('generator', 'Venus')
define_planet('generator_uri', 'http://intertwingly.net/code/venus/')
define_planet('owner_name', 'Anonymous Coward')
define_planet('owner_email', '')
define_planet('output_theme', '')
define_planet('output_dir', 'output')
define_planet('feed', None)
define_planet_list('template_files')
define_planet_list('bill_of_materials')
@ -160,8 +162,25 @@ def cache_lists_directory():
else:
return os.path.join(cache_directory(), 'lists')
def feeds():
""" list the feeds defined """
def feed():
if parser.has_option('Planet', 'feed'):
parser.get('Planet', 'feed')
elif link():
for template_file in template_files:
name = os.path.splitext(os.path.basename(template_file))[0]
if name.find('atom')>=0 or name.find('rss')>=0:
return urlparse.urljoin(link(), name)
def feedtype():
if parser.has_option('Planet', 'feedtype'):
parser.get('Planet', 'feedtype')
elif feed() and feed().find('atom')>=0:
return 'atom'
elif feed() and feed().find('rss')>=0:
return 'rss'
def subscriptions():
""" list the feed subscriptions """
return filter(lambda feed: feed!='Planet' and feed not in template_files(),
parser.sections())

View File

@ -1,5 +1,5 @@
from xml.sax.saxutils import escape
import sgmllib, time, os, sys
import sgmllib, time, os, sys, new, urlparse
from planet import config, feedparser, htmltmpl
class stripHtml(sgmllib.SGMLParser):
@ -54,6 +54,9 @@ def Plain(value):
def PlanetDate(value):
return time.strftime(config.date_format(), value)
def NewDate(value):
return time.strftime(config.new_date_format(), value)
def Rfc822(value):
return time.strftime("%a, %d %b %Y %H:%M:%S +0000", value)
@ -64,7 +67,6 @@ def Rfc3399(value):
Base = [
['author', String, 'author'],
['author_name', String, 'author_detail', 'name'],
['feed', String, 'links', {'rel':'self'}, 'href'],
['generator', String, 'generator'],
['id', String, 'id'],
['icon', String, 'icon'],
@ -76,9 +78,9 @@ Base = [
['subtitle', String, 'subtitle_detail', 'value'],
['title', String, 'title_detail', 'value'],
['title_plain', Plain, 'title_detail', 'value'],
['url', String, 'links', {'rel':'self'}, 'href'],
]
# ? new_date, new_channel
Items = [
['author', String, 'author'],
['author_email', String, 'author_detail', 'email'],
@ -95,6 +97,9 @@ Items = [
['date_iso', Rfc3399, 'updated_parsed'],
['id', String, 'id'],
['link', String, 'links', {'rel': 'alternate'}, 'href'],
['new_channel', String, 'id'],
['new_date', NewDate, 'published_parsed'],
['new_date', NewDate, 'updated_parsed'],
['rights', String, 'rights_detail', 'value'],
['title_language', String, 'title_detail', 'language'],
['title_plain', Plain, 'title_detail', 'value'],
@ -108,14 +113,6 @@ Items = [
['published_iso', Rfc3399, 'published_parsed'],
]
Channels = [
['url', None],
['link', None],
['message', None],
['title_plain', None],
['name', None],
]
# Add additional rules for source information
for rule in Base:
Items.append(['channel_'+rule[0], rule[1], 'source'] + rule[2:])
@ -161,13 +158,67 @@ def tmpl_mapper(source, rules):
return output
def _end_planet_source(self):
self._end_source()
context = self._getContext()
if not context.has_key('sources'): context['sources'] = []
context.sources.append(context.source)
del context['source']
def template_info(source):
""" get template information from a feedparser output """
# wire in support for planet:source, call feedparser, unplug planet:source
mixin=feedparser._FeedParserMixin
mixin._start_planet_source = mixin._start_source
mixin._end_planet_source = \
new.instancemethod(_end_planet_source, None, mixin)
data=feedparser.parse(source)
del mixin._start_planet_source
del mixin._end_planet_source
# apply rules to convert feed parser output to htmltmpl input
output = {'Channels': [], 'Items': []}
output['Channels'].append(tmpl_mapper(data.feed, Base))
output.update(tmpl_mapper(data.feed, Base))
sources = [(source.get('planet_name',None),source)
for source in data.feed.get('sources',[])]
sources.sort()
for name, feed in sources:
output['Channels'].append(tmpl_mapper(feed, Base))
for entry in data.entries:
output['Items'].append(tmpl_mapper(entry, Items))
# feed level information
output['generator'] = config.generator_uri()
output['name'] = config.name()
output['link'] = config.link()
output['owner_name'] = config.owner_name()
output['owner_email'] = config.owner_email()
if config.feed():
output['feed'] = config.feed()
output['feedtype'] = config.feed().find('rss')>=0 and 'rss' or 'atom'
# date/time information
date = time.gmtime()
output['date'] = PlanetDate(date)
output['date_iso'] = Rfc3399(date)
output['date_822'] = Rfc822(date)
# remove new_dates and new_channels that aren't "new"
date = channel = None
for item in output['Items']:
if item.has_key('new_date'):
if item['new_date'] == date:
del item['new_date']
else:
date = item['new_date']
if item.has_key('new_channel'):
if item['new_channel'] == channel:
del item['new_channel']
else:
channel = item['new_channel']
return output
def run(script, doc, output_file=None):
@ -177,6 +228,10 @@ def run(script, doc, output_file=None):
tp = htmltmpl.TemplateProcessor(html_escape=0)
for key,value in template_info(doc).items():
tp.set(key, value)
reluri = os.path.splitext(os.path.basename(output_file))[0]
tp.set('url', urlparse.urljoin(config.link(),reluri))
output = open(output_file, "w")
output.write(tp.process(template))
output.close()

View File

@ -147,5 +147,5 @@ def spiderPlanet(configFile):
log = planet.getLogger(config.log_level())
planet.setTimeout(config.feed_timeout())
for feed in config.feeds():
for feed in config.subscriptions():
spiderFeed(feed)

View File

@ -42,7 +42,7 @@ def splice(configFile):
# insert subscription information
feed.setAttribute('xmlns:planet',planet.xmlns)
sources = config.cache_sources_directory()
for sub in config.feeds():
for sub in config.subscriptions():
data=feedparser.parse(filename(sources,sub))
if not data.feed: continue
xdoc=minidom.parseString('''<planet:source xmlns:planet="%s"

View File

@ -0,0 +1,7 @@
;
; Description: id
; Expect: feed == 'http://example.com/atom.xml' and feedtype == 'atom'
;
[Planet]
feed: http://example.com/atom.xml

View File

@ -0,0 +1,7 @@
;
; Description: id
; Expect: generator == 'http://example.com/planet'
;
[Planet]
generator_uri: http://example.com/planet

View File

@ -0,0 +1,7 @@
;
; Description: id
; Expect: link == 'http://example.com/planet'
;
[Planet]
link: http://example.com/planet

View File

@ -0,0 +1,7 @@
;
; Description: id
; Expect: name == 'My Planet'
;
[Planet]
name: My Planet

View File

@ -0,0 +1,7 @@
;
; Description: id
; Expect: owner_email == 'me@example.com'
;
[Planet]
owner_email: me@example.com

View File

@ -0,0 +1,7 @@
;
; Description: id
; Expect: owner_name == 'me'
;
[Planet]
owner_name: me

View File

@ -1,14 +1,16 @@
<!--
Description: id
Expect: Channels[0]['name'] == 'foo'
Expect: Channels[0]['name'] == 'foo' and Items[0]['channel_name'] == 'foo'
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<planet:name>foo</planet:name>
<entry>
<source>
<planet:name>foo</planet:name>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<planet:name>foo</planet:name>
</planet:source>
</feed>

View File

@ -4,9 +4,6 @@ Expect: Channels[0]['author'] == 'John Doe' and Channels[0]['author_name']
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<author>
<name>John Doe</name>
</author>
<entry>
<source>
<author>
@ -14,5 +11,10 @@ Expect: Channels[0]['author'] == 'John Doe' and Channels[0]['author_name']
</author>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<author>
<name>John Doe</name>
</author>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['icon'] == 'http://www.example.com/favicon.ico' and It
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<icon>http://www.example.com/favicon.ico</icon>
<entry>
<source>
<icon>http://www.example.com/favicon.ico</icon>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<icon>http://www.example.com/favicon.ico</icon>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['id'] == 'http://example.com/' and Items[0]['channel_i
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<id>http://example.com/</id>
<entry>
<source>
<id>http://example.com/</id>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<id>http://example.com/</id>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['logo'] == 'http://www.example.com/logo.jpg' and Items
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<logo>http://www.example.com/logo.jpg</logo>
<entry>
<source>
<logo>http://www.example.com/logo.jpg</logo>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<logo>http://www.example.com/logo.jpg</logo>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['name'] == 'foo' and Items[0]['channel_name'] == 'foo'
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<planet:name>foo</planet:name>
<entry>
<source>
<planet:name>foo</planet:name>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<planet:name>foo</planet:name>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['rights'] == '&copy; 2006' and Items[0]['channel_right
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<rights type="html">&amp;copy; 2006</rights>
<entry>
<source>
<rights type="html">&amp;copy; 2006</rights>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<rights type="html">&amp;copy; 2006</rights>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['subtitle'] == 'snarky phrase' and Items[0]['channel_s
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<subtitle>snarky phrase</subtitle>
<entry>
<source>
<subtitle>snarky phrase</subtitle>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<subtitle>snarky phrase</subtitle>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['title'] == 'visible name' and Channels[0]['title_plai
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>visible name</title>
<entry>
<source>
<title>visible name</title>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<title>visible name</title>
</planet:source>
</feed>

View File

@ -4,11 +4,13 @@ Expect: Channels[0]['last_updated_iso'] == '2004-02-29T02:14:55+00:00' and
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<updated>2004-02-28T18:14:55-08:00</updated>
<entry>
<source>
<updated>2004-02-28T18:14:55-08:00</updated>
</source>
</entry>
<planet:source xmlns:planet='http://planet.intertwingly.net/'>
<updated>2004-02-28T18:14:55-08:00</updated>
</planet:source>
</feed>

View File

@ -14,7 +14,7 @@ class ConfigTest(unittest.TestCase):
config.template_files())
def test_feeds(self):
feeds = config.feeds()
feeds = config.subscriptions()
feeds.sort()
self.assertEqual(['feed1', 'feed2'], feeds)
@ -24,7 +24,7 @@ class ConfigTest(unittest.TestCase):
self.assertEqual('Test Configuration', config.name())
def test_link(self):
self.assertEqual('Unconfigured Planet', config.link())
self.assertEqual('', config.link())
# per template configuration

View File

@ -1,20 +1,22 @@
#!/usr/bin/env python
import unittest, os, sys, glob, new, re, StringIO, time
from planet import config
from planet.shell import tmpl
testfiles = 'tests/data/filter/tmpl/%s.xml'
testfiles = 'tests/data/filter/tmpl/%s.%s'
class FilterTmplTest(unittest.TestCase):
desc_re = re.compile("Description:\s*(.*?)\s*Expect:\s*(.*)\s*-->")
desc_feed_re = re.compile("Description:\s*(.*?)\s*Expect:\s*(.*)\s*-->")
desc_config_re = re.compile(";\s*Description:\s*(.*?)\s*;\s*Expect:\s*(.*)")
simple_re = re.compile("^(\S+) == (u?'[^']*'|\([0-9, ]+\))$")
def eval(self, name):
def eval_feed(self, name):
# read the test case
try:
testcase = open(testfiles % name)
testcase = open(testfiles % (name,'xml'))
data = testcase.read()
description, expect = self.desc_re.search(data).groups()
description, expect = self.desc_feed_re.search(data).groups()
testcase.close()
except:
raise RuntimeError, "can't parse %s" % name
@ -29,9 +31,37 @@ class FilterTmplTest(unittest.TestCase):
lhs, rhs = self.simple_re.match(expect).groups()
self.assertEqual(eval(rhs), eval(lhs, results))
# build a test method for each test file
for testcase in glob.glob(testfiles % '*'):
def eval_config(self, name):
# read the test case
try:
testcase = open(testfiles % (name,'ini'))
data = testcase.read()
description, expect = self.desc_config_re.search(data).groups()
testcase.close()
except:
raise RuntimeError, "can't parse %s" % name
# map to template info
config.load(testfiles % (name,'ini'))
results = tmpl.template_info("<feed/>")
# verify the results
if not self.simple_re.match(expect):
self.assertTrue(eval(expect, results), expect)
else:
lhs, rhs = self.simple_re.match(expect).groups()
self.assertEqual(eval(rhs), eval(lhs, results))
# build a test method for each xml test file
for testcase in glob.glob(testfiles % ('*','xml')):
root = os.path.splitext(os.path.basename(testcase))[0]
func = lambda self, name=root: self.eval(name)
func = lambda self, name=root: self.eval_feed(name)
method = new.instancemethod(func, None, FilterTmplTest)
setattr(FilterTmplTest, "test_" + root, method)
# build a test method for each ini test file
for testcase in glob.glob(testfiles % ('*','ini')):
root = os.path.splitext(os.path.basename(testcase))[0]
func = lambda self, name=root: self.eval_config(name)
method = new.instancemethod(func, None, FilterTmplTest)
setattr(FilterTmplTest, "test_" + root, method)

View File

@ -19,7 +19,7 @@ class ReadingListTest(unittest.TestCase):
# administrivia
def test_feeds(self):
feeds = [split(feed)[1] for feed in config.feeds()]
feeds = [split(feed)[1] for feed in config.subscriptions()]
feeds.sort()
self.assertEqual(['testfeed0.atom', 'testfeed1a.atom',
'testfeed2.atom', 'testfeed3.rss'], feeds)
@ -27,7 +27,7 @@ class ReadingListTest(unittest.TestCase):
# dictionaries
def test_feed_options(self):
feeds = dict([(split(feed)[1],feed) for feed in config.feeds()])
feeds = dict([(split(feed)[1],feed) for feed in config.subscriptions()])
feed1 = feeds['testfeed1a.atom']
self.assertEqual('one', config.feed_options(feed1)['name'])

View File

@ -20,7 +20,7 @@ class ConfigTest(unittest.TestCase):
self.assertTrue('index.html.xslt' in config.template_files())
def test_feeds(self):
feeds = config.feeds()
feeds = config.subscriptions()
feeds.sort()
self.assertEqual(['feed1', 'feed2'], feeds)
@ -30,7 +30,7 @@ class ConfigTest(unittest.TestCase):
self.assertEqual('Test Configuration', config.name())
def test_link(self):
self.assertEqual('Unconfigured Planet', config.link())
self.assertEqual('', config.link())
# per template configuration

View File

@ -1,10 +1,9 @@
# This template is based on the one originally developed by Stefano Mazzocci
# This theme is based on the one originally developed by Stefano Mazzocci
# for planetapache.org, and modified by Sam Ruby for planet.intertwingly.net
[Planet]
template_files:
atom.xml.xslt
rss20.xml.tmpl
foafroll.xml.xslt
index.html.xslt
opml.xml.xslt

View File

@ -0,0 +1,20 @@
# This theme is based on the one contained in Planet V2.0. It demonstrates
# that one can mix the use of htmltmpl and xslt templates.
[Planet]
template_files:
atom.xml.xslt
foafroll.xml.xslt
index.html.tmpl
opml.xml.xslt
rss10.xml.tmpl
rss20.xml.tmpl
template_directories:
../common
bill_of_materials:
planet.css
images/feed-icon-10x10.png
images/logo.png
images/planet.png

View File

@ -0,0 +1,126 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
### Fancy Planet HTML template.
###
### When combined with the stylesheet and images in the output/ directory
### of the Planet source, this gives you a much prettier result than the
### default examples template and demonstrates how to use the config file
### to support things like faces
###
### For documentation on the more boring template elements, see
### examples/config.ini and examples/index.html.tmpl in the Planet source.
<head>
<title><TMPL_VAR name></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="<TMPL_VAR generator ESCAPE="HTML">">
<link rel="stylesheet" href="planet.css" type="text/css">
<TMPL_IF feedtype>
<link rel="alternate" href="<TMPL_VAR feed ESCAPE="HTML">" title="<TMPL_VAR channel_title_plain ESCAPE="HTML">" type="application/<TMPL_VAR feedtype>+xml">
</TMPL_IF>
</head>
<body>
<h1><TMPL_VAR name></h1>
<TMPL_VAR admin>
<TMPL_LOOP Items>
<TMPL_IF new_date>
<TMPL_UNLESS __FIRST__>
### End <div class="channelgroup">
</div>
### End <div class="daygroup">
</div>
</TMPL_UNLESS>
<div class="daygroup">
<h2><TMPL_VAR new_date></h2>
</TMPL_IF>
<TMPL_IF new_channel>
<TMPL_UNLESS new_date>
### End <div class="channelgroup">
</div>
</TMPL_UNLESS>
<div class="channelgroup">
### Planet provides template variables for *all* configuration options for
### the channel (and defaults), even if it doesn't know about them. We
### exploit this here to add hackergotchi faces to our channels. Planet
### doesn't know about the "face", "facewidth" and "faceheight" configuration
### variables, but makes them available to us anyway.
<h3><a href="<TMPL_VAR channel_link ESCAPE="HTML">" title="<TMPL_VAR channel_title_plain ESCAPE="HTML">"><TMPL_VAR channel_name></a></h3>
<TMPL_IF channel_face>
<img class="face" src="images/<TMPL_VAR channel_face ESCAPE="HTML">" width="<TMPL_VAR channel_facewidth ESCAPE="HTML">" height="<TMPL_VAR channel_faceheight ESCAPE="HTML">" alt="">
</TMPL_IF>
</TMPL_IF>
<div class="entrygroup" id="<TMPL_VAR id>"<TMPL_IF channel_language> lang="<TMPL_VAR channel_language>"</TMPL_IF>>
<TMPL_IF title>
<h4<TMPL_IF title_language> lang="<TMPL_VAR title_language>"</TMPL_IF>><a href="<TMPL_VAR link ESCAPE="HTML">"><TMPL_VAR title></a></h4>
</TMPL_IF>
<div class="entry">
<div class="content"<TMPL_IF content_language> lang="<TMPL_VAR content_language>"</TMPL_IF>>
<TMPL_VAR content>
</div>
### Planet also makes available all of the information from the feed
### that it can. Use the 'planet-cache' tool on the cache file for
### a particular feed to find out what additional keys it supports.
### Comment extra fields are 'author' and 'category' which we
### demonstrate below.
<p class="date">
<a href="<TMPL_VAR link ESCAPE="HTML">"><TMPL_IF author>by <TMPL_VAR author ESCAPE="HTML"> at </TMPL_IF><TMPL_VAR date><TMPL_IF category> under <TMPL_VAR category></TMPL_IF></a>
</p>
</div>
</div>
<TMPL_IF __LAST__>
### End <div class="channelgroup">
</div>
### End <div class="daygroup">
</div>
</TMPL_IF>
</TMPL_LOOP>
<div class="sidebar">
<img src="images/logo.png" width="136" height="136" alt="">
<h2>Subscriptions</h2>
<ul>
<TMPL_LOOP Channels>
<li>
<a href="<TMPL_VAR url ESCAPE="HTML">" title="subscribe"><img src="images/feed-icon-10x10.png" alt="(feed)"></a> <a <TMPL_IF link>href="<TMPL_VAR link ESCAPE="HTML">" </TMPL_IF><TMPL_IF message>class="message" title="<TMPL_VAR message ESCAPE="HTML">"</TMPL_IF><TMPL_UNLESS message>title="<TMPL_VAR title_plain ESCAPE="HTML">"</TMPL_UNLESS>><TMPL_VAR name></a>
</li>
</TMPL_LOOP>
</ul>
<p>
<strong>Last updated:</strong><br>
<TMPL_VAR date><br>
<em>All times are UTC.</em><br>
<br>
Powered by:<br>
<a href="http://www.planetplanet.org/"><img src="images/planet.png" width="80" height="15" alt="Planet" border="0"></a>
</p>
<p>
<h2>Planetarium:</h2>
<ul>
<li><a href="http://www.planetapache.org/">Planet Apache</a></li>
<li><a href="http://planet.debian.net/">Planet Debian</a></li>
<li><a href="http://planet.freedesktop.org/">Planet freedesktop.org</a></li>
<li><a href="http://planet.gnome.org/">Planet GNOME</a></li>
<li><a href="http://planetsun.org/">Planet Sun</a></li>
<li><a href="http://fedora.linux.duke.edu/fedorapeople/">Fedora People</a></li>
<li><a href="http://www.planetplanet.org/">more...</a></li>
</ul>
</p>
</div>
</body>
</html>

View File

@ -0,0 +1,150 @@
body {
border-right: 1px solid black;
margin-right: 200px;
padding-left: 20px;
padding-right: 20px;
}
h1 {
margin-top: 0px;
padding-top: 20px;
font-family: "Bitstream Vera Sans", sans-serif;
font-weight: normal;
letter-spacing: -2px;
text-transform: lowercase;
text-align: right;
color: grey;
}
.admin {
text-align: right;
}
h2 {
font-family: "Bitstream Vera Sans", sans-serif;
font-weight: normal;
color: #200080;
margin-left: -20px;
}
h3 {
font-family: "Bitstream Vera Sans", sans-serif;
font-weight: normal;
background-color: #a0c0ff;
border: 1px solid #5080b0;
padding: 4px;
}
h3 a {
text-decoration: none;
color: inherit;
}
h4 {
font-family: "Bitstream Vera Sans", sans-serif;
font-weight: bold;
}
h4 a {
text-decoration: none;
color: inherit;
}
img.face {
float: right;
margin-top: -3em;
}
.entry {
margin-bottom: 2em;
}
.entry .date {
font-family: "Bitstream Vera Sans", sans-serif;
color: grey;
}
.entry .date a {
text-decoration: none;
color: inherit;
}
.sidebar {
position: absolute;
top: 0px;
right: 0px;
width: 200px;
margin-left: 0px;
margin-right: 0px;
padding-right: 0px;
padding-top: 20px;
padding-left: 0px;
font-family: "Bitstream Vera Sans", sans-serif;
font-size: 85%;
}
.sidebar h2 {
font-size: 110%;
font-weight: bold;
color: black;
padding-left: 5px;
margin-left: 0px;
}
.sidebar ul {
padding-left: 1em;
margin-left: 0px;
list-style-type: none;
}
.sidebar ul li:hover {
color: grey;
}
.sidebar ul li a {
text-decoration: none;
}
.sidebar ul li a:hover {
text-decoration: underline;
}
.sidebar ul li a img {
border: 0;
}
.sidebar p {
border-top: 1px solid grey;
margin-top: 30px;
padding-top: 10px;
padding-left: 5px;
}
.sidebar .message {
cursor: help;
border-bottom: 1px dashed red;
}
.sidebar a.message:hover {
cursor: help;
background-color: #ff0000;
color: #ffffff !important;
text-decoration: none !important;
}
a:hover {
text-decoration: underline !important;
color: blue !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,37 @@
<?xml version="1.0"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns="http://purl.org/rss/1.0/"
>
<channel rdf:about="<TMPL_VAR link ESCAPE="HTML">">
<title><TMPL_VAR name ESCAPE="HTML"></title>
<link><TMPL_VAR link ESCAPE="HTML"></link>
<description><TMPL_VAR name ESCAPE="HTML"> - <TMPL_VAR link ESCAPE="HTML"></description>
<items>
<rdf:Seq>
<TMPL_LOOP Items>
<rdf:li rdf:resource="<TMPL_VAR id ESCAPE="HTML">" />
</TMPL_LOOP>
</rdf:Seq>
</items>
</channel>
<TMPL_LOOP Items>
<item rdf:about="<TMPL_VAR id ESCAPE="HTML">">
<title><TMPL_VAR channel_name ESCAPE="HTML"><TMPL_IF title>: <TMPL_VAR title_plain ESCAPE="HTML"></TMPL_IF></title>
<link><TMPL_VAR link ESCAPE="HTML"></link>
<TMPL_IF content>
<content:encoded><TMPL_VAR content ESCAPE="HTML"></content:encoded>
</TMPL_IF>
<dc:date><TMPL_VAR date_iso></dc:date>
<TMPL_IF author_name>
<dc:creator><TMPL_VAR author_name></dc:creator>
</TMPL_IF>
</item>
</TMPL_LOOP>
</rdf:RDF>