forked from sch/Blasta
Graphic : Add an icon for syndication page;
HTML : Add an XML template for The Atom Syndication Format; Python : Add support for The Atom Syndication Format; README : Add screenshots; XSLT : Add an XSL Transformations stylesheet.
This commit is contained in:
parent
3d9e5b2e02
commit
164b4d67d4
34 changed files with 578 additions and 18 deletions
|
@ -15,6 +15,11 @@ types adc, dweb, ed2k, feed, ftp, gemini, geo, gopher, http, ipfs, irc, magnet,
|
|||
mailto, monero, mms, news, sip, udp, xmpp and any scheme and type that you
|
||||
desire.
|
||||
|
||||
## Screenshots
|
||||
|
||||
[<img alt="browse view" src="graphic/browse.png" width="200px"/>](screenshot/browse.png)
|
||||
[<img alt="tags view" src="graphic/tag.png" width="200px"/>](screenshot/tag.png)
|
||||
|
||||
## Technicalities
|
||||
|
||||
Blasta is a federated bookmarking system which is based on XMPP and stores
|
||||
|
@ -45,7 +50,6 @@ The connection to the Blasta system is made with XMPP accounts.
|
|||
## Future features
|
||||
|
||||
- ActivityPub;
|
||||
- Atom Syndication Format;
|
||||
- Federation;
|
||||
- Filters;
|
||||
- Pin;
|
||||
|
|
38
blasta.py
38
blasta.py
|
@ -261,15 +261,12 @@ class HttpInstance:
|
|||
def __init__(self, accounts, sessions):
|
||||
|
||||
self.app = FastAPI()
|
||||
#templates = Jinja2Templates(directory='xhtml/template')
|
||||
templates = Jinja2Templates(directory='xhtml')
|
||||
templates = Jinja2Templates(directory='template')
|
||||
|
||||
self.app.mount('/data', StaticFiles(directory='data'), name='data')
|
||||
self.app.mount('/export', StaticFiles(directory='export'), name='export')
|
||||
self.app.mount('/graphic', StaticFiles(directory='graphic'), name='graphic')
|
||||
self.app.mount('/stylesheet', StaticFiles(directory='stylesheet'), name='stylesheet')
|
||||
#self.app.mount('/policy', StaticFiles(directory='xhtml/policy'), name='policy')
|
||||
#self.app.mount('/xhtml', StaticFiles(directory='xhtml'), name='xhtml')
|
||||
|
||||
filename_configuration = 'configuration.toml'
|
||||
data = Data.open_file_toml(filename_configuration)
|
||||
|
@ -721,13 +718,14 @@ class HttpInstance:
|
|||
related_tags = None
|
||||
tags_dict = None
|
||||
param_filetype = request.query_params.get('filetype', '') or None
|
||||
param_mode = request.query_params.get('mode', '') or None
|
||||
param_page = request.query_params.get('page', '') or None
|
||||
param_protocol = request.query_params.get('protocol', '') or None
|
||||
param_query = request.query_params.get('q', '') or None
|
||||
if param_query: param_query = param_query.strip()
|
||||
param_tags = request.query_params.get('tags', '') or None
|
||||
param_tld = request.query_params.get('tld', '') or None
|
||||
if param_page:
|
||||
if param_page and param_mode != 'feed':
|
||||
try:
|
||||
page = int(param_page)
|
||||
page_next = page + 1
|
||||
|
@ -979,7 +977,6 @@ class HttpInstance:
|
|||
message = 'Blasta system message » Please connect with your XMPP account to view this directory.'
|
||||
path = 'error'
|
||||
return result_post(request, jabber_id, description, message, path)
|
||||
template_file = 'browse.xhtml'
|
||||
template_dict = {
|
||||
'request': request,
|
||||
'description': description,
|
||||
|
@ -999,8 +996,14 @@ class HttpInstance:
|
|||
'start': start,
|
||||
'syndicate': jid,
|
||||
'tags' : tags_dict or related_tags or ''}
|
||||
response = templates.TemplateResponse(template_file, template_dict)
|
||||
response.headers["Content-Type"] = "application/xhtml+xml"
|
||||
if param_mode == 'feed':
|
||||
template_file = 'browse.atom'
|
||||
response = templates.TemplateResponse(template_file, template_dict)
|
||||
response.headers["Content-Type"] = "application/xml"
|
||||
else:
|
||||
template_file = 'browse.xhtml'
|
||||
response = templates.TemplateResponse(template_file, template_dict)
|
||||
response.headers["Content-Type"] = "application/xhtml+xml"
|
||||
return response
|
||||
|
||||
@self.app.get('/blasta.svg')
|
||||
|
@ -1031,14 +1034,15 @@ class HttpInstance:
|
|||
async def root_main_get(request: Request, response : Response, page_type=None):
|
||||
jabber_id = Utilities.is_jid_matches_to_session(accounts, sessions, request)
|
||||
node_id = path = syndicate = page_type
|
||||
param_filetype = request.query_params.get('filetype', '') or None
|
||||
param_mode = request.query_params.get('mode', '') or None
|
||||
param_page = request.query_params.get('page', '') or None
|
||||
param_protocol = request.query_params.get('protocol', '') or None
|
||||
param_query = request.query_params.get('q', '') or None
|
||||
if param_query: param_query = param_query.strip()
|
||||
param_page = request.query_params.get('page', '') or None
|
||||
param_tags = request.query_params.get('tags', '') or None
|
||||
param_tld = request.query_params.get('tld', '') or None
|
||||
param_filetype = request.query_params.get('filetype', '') or None
|
||||
param_protocol = request.query_params.get('protocol', '') or None
|
||||
if param_page:
|
||||
if param_page and param_mode != 'feed':
|
||||
try:
|
||||
page = int(param_page)
|
||||
page_next = page + 1
|
||||
|
@ -1154,8 +1158,14 @@ class HttpInstance:
|
|||
'pubsub_jid' : jabber_id_pubsub,
|
||||
'syndicate' : syndicate,
|
||||
'tags' : tags_dict}
|
||||
response = templates.TemplateResponse(template_file, template_dict)
|
||||
response.headers["Content-Type"] = "application/xhtml+xml"
|
||||
if param_mode == 'feed':
|
||||
template_file = 'browse.atom'
|
||||
response = templates.TemplateResponse(template_file, template_dict)
|
||||
response.headers["Content-Type"] = "application/xml"
|
||||
else:
|
||||
template_file = 'browse.xhtml'
|
||||
response = templates.TemplateResponse(template_file, template_dict)
|
||||
response.headers["Content-Type"] = "application/xhtml+xml"
|
||||
return response
|
||||
|
||||
"""
|
||||
|
|
6
graphic/blasta_syndicate.svg
Normal file
6
graphic/blasta_syndicate.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="25" height="25" fill="#fff" />
|
||||
<rect x="25" y="0" width="25" height="25" fill="#d9541e" />
|
||||
<rect x="0" y="25" width="25" height="25" fill="#CC5D15" />
|
||||
<rect x="25" y="25" width="25" height="25" fill="#d3d2d2" />
|
||||
</svg>
|
After Width: | Height: | Size: 316 B |
BIN
screenshot/browse.png
Normal file
BIN
screenshot/browse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 KiB |
BIN
screenshot/tag.png
Normal file
BIN
screenshot/tag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 279 KiB |
491
stylesheet/stylesheet.xsl
Normal file
491
stylesheet/stylesheet.xsl
Normal file
|
@ -0,0 +1,491 @@
|
|||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
|
||||
<xsl:stylesheet version='1.0'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
|
||||
xmlns:xml='http://www.w3.org/XML/1998/namespace'
|
||||
xmlns:media='http://search.yahoo.com/mrss/'
|
||||
xmlns:georss='http://www.georss.org/georss'
|
||||
xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#'
|
||||
xmlns:atom10='http://www.w3.org/2005/Atom'
|
||||
xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||
|
||||
<xsl:output
|
||||
method = 'html'
|
||||
indent = 'yes'
|
||||
omit-xml-decleration='no' />
|
||||
|
||||
<!-- set page metadata -->
|
||||
<xsl:template name='metadata'>
|
||||
<xsl:param name='name'/>
|
||||
<xsl:param name='content'/>
|
||||
<xsl:if test='$content and not($content="")'>
|
||||
<xsl:element name='meta'>
|
||||
<xsl:attribute name='name'>
|
||||
<xsl:value-of select='$name'/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='content'>
|
||||
<xsl:value-of select='$content'/>
|
||||
</xsl:attribute>
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='/atom:feed'>
|
||||
<!-- index right-to-left language codes -->
|
||||
<!-- TODO http://www.w3.org/TR/xpath/#function-lang -->
|
||||
<xsl:variable name='rtl'
|
||||
select='@xml:lang[
|
||||
contains(self::node(),"ar") or
|
||||
contains(self::node(),"fa") or
|
||||
contains(self::node(),"he") or
|
||||
contains(self::node(),"ji") or
|
||||
contains(self::node(),"ku") or
|
||||
contains(self::node(),"ur") or
|
||||
contains(self::node(),"yi")]'/>
|
||||
<html>
|
||||
<head>
|
||||
<xsl:call-template name='metadata'>
|
||||
<xsl:with-param name='name' select='"description"' />
|
||||
<xsl:with-param name='content' select='atom:subtitle' />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name='metadata'>
|
||||
<xsl:with-param name='name' select='"generator"' />
|
||||
<xsl:with-param name='content' select='"Blasta"' />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name='metadata'>
|
||||
<xsl:with-param name='name' select='"mimetype"' />
|
||||
<xsl:with-param name='content' select='"application/atom+xml"' />
|
||||
</xsl:call-template>
|
||||
<title>
|
||||
<xsl:value-of select='atom:title'/>
|
||||
</title>
|
||||
<link rel='stylesheet' type='text/css' media='screen' href='/stylesheet/stylesheet.css'/>
|
||||
<link rel='icon' type='image/svg+xml' href='/graphic/blasta.svg'/>
|
||||
</head>
|
||||
<body>
|
||||
<div id='header'>
|
||||
<!-- feed title -->
|
||||
<h1>
|
||||
<img src='/graphic/blasta_syndicate.svg'/>
|
||||
 
|
||||
<xsl:value-of select='atom:title'/>
|
||||
</h1>
|
||||
<dl id='navigation'>
|
||||
<dd>
|
||||
<img src='/graphic/blasta_syndicate.svg'/>
|
||||
</dd>
|
||||
<dd>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:value-of select='atom:link'/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='id'>follow</xsl:attribute>
|
||||
<xsl:attribute name='title'>Subscribe to updates with a news reader software.</xsl:attribute>
|
||||
Follow
|
||||
</xsl:element>
|
||||
</dd>
|
||||
<dd>
|
||||
<a id='subtome' title='Subscribe via SubToMe.'>
|
||||
<xsl:attribute name='href'>
|
||||
javascript:location.href='https://www.subtome.com/#/subscribe?feeds='+location.href;
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='onclick'>
|
||||
(
|
||||
function(btn){
|
||||
var z=document.createElement('script');
|
||||
document.subtomeBtn=btn;
|
||||
z.src='https://www.subtome.com/load.js';document.body.appendChild(z);
|
||||
}
|
||||
)(this);
|
||||
return false;
|
||||
</xsl:attribute>
|
||||
SubToMe
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='/help/about/xmpp'
|
||||
title='Of the benefits of XMPP.'>
|
||||
XMPP
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://xmpp.link/#syndication@conference.movim.eu?join'
|
||||
title='Syndictaion and PubSub.'>
|
||||
Groupchat
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='/help/feeds'
|
||||
title='Of the benefits of syndication feed.'
|
||||
id='aboutfeeds'>
|
||||
Help
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<xsl:if test='count(atom:entry) > 1'>
|
||||
<div>
|
||||
<h3>
|
||||
<img src='/graphic/syndicate.svg' height='22' width='22'/>
|
||||
 
|
||||
<xsl:value-of select='atom:subtitle'/>
|
||||
</h3>
|
||||
<!-- xsl:for-each select='atom:entry[position() <21]' -->
|
||||
<ul>
|
||||
<xsl:for-each select='atom:entry[not(position() > 20)]'>
|
||||
<li>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:text>#blasta-</xsl:text>
|
||||
<xsl:value-of select='position()'/>
|
||||
</xsl:attribute>
|
||||
<xsl:choose>
|
||||
<xsl:when test='string-length(atom:title) > 0'>
|
||||
<xsl:value-of select='atom:title'/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
*** No Title ***
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:element>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</div>
|
||||
</xsl:if>
|
||||
<div id='main'>
|
||||
<!-- feed entry -->
|
||||
<dl>
|
||||
<dd>
|
||||
<article class='title'>
|
||||
<h4 class='title'>
|
||||
<a href='/help/feeds'>
|
||||
This is an automated Blasta Syndication Feed
|
||||
</a>
|
||||
</h4>
|
||||
<h5 class='related'>
|
||||
 
|
||||
<img alt='💡'
|
||||
height='16'
|
||||
src='/graphic/xmpp.svg'
|
||||
width='16' />
|
||||
 
|
||||
<a href='/help/about/xmpp/pubsub'>XMPP</a>
|
||||
 
|
||||
<img alt='⚛'
|
||||
class='enlarge'
|
||||
height='16'
|
||||
src='/graphic/syndicate.svg'
|
||||
width='16' />
|
||||
 
|
||||
<a href='/help/syndication'>Syndication</a>
|
||||
</h5>
|
||||
<p>
|
||||
<b>Congratulations!</b> You have reached to the final
|
||||
frontier that the XML technology has to offer
|
||||
to-date, and as of yet!
|
||||
</p>
|
||||
<p>
|
||||
This is an automated Blasta Syndication Feed
|
||||
which you can utilize to gracefully receive
|
||||
autmatic Blasta updates.
|
||||
</p>
|
||||
<p>
|
||||
<a href='/help/syndication#software'>Click
|
||||
here</a> for a selection of software and pick
|
||||
the ones that would fit to you best!
|
||||
</p>
|
||||
<div class='details'>
|
||||
<a href='?tags=filetype:atom'>filetype:atom </a>
|
||||
<a href='?tags=filetype:rss'>filetype:rss </a>
|
||||
<a href='?tags=filetype:xml'>filetype:xml </a>
|
||||
<a href='?tags=software:akregator'>software:akregator </a>
|
||||
<a href='?tags=software:fraidycat'>software:fraidycat </a>
|
||||
<a href='?tags=software:liferea'>software:liferea </a>
|
||||
<a href='?tags=software:otter-browser'>software:otter-browser </a>
|
||||
<a href='?tags=software:raven-reader'>software:raven-reader </a>
|
||||
<a href='?tags=niche:syndication'>niche:syndication</a>
|
||||
<h5 class='updated'>2024-08-22T17:09:04+03:00</h5>
|
||||
<h5 class='author'>
|
||||
<a href='/jid/sch@pimux.de'>sch@pimux.de</a>
|
||||
</h5>
|
||||
</div>
|
||||
</article>
|
||||
</dd>
|
||||
<xsl:choose>
|
||||
<xsl:when test='atom:entry'>
|
||||
<xsl:for-each select='atom:entry[not(position() >20)]'>
|
||||
<dd>
|
||||
<article class='title'>
|
||||
<!-- entry title -->
|
||||
<h4 class='title'>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:choose>
|
||||
<xsl:when test='atom:link[@rel="self"]'>
|
||||
<xsl:value-of select='atom:link[@rel="self"]/@href'/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select='atom:link/@href'/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='id'>
|
||||
<xsl:text>blasta-</xsl:text>
|
||||
<xsl:value-of select='position()'/>
|
||||
</xsl:attribute>
|
||||
<xsl:choose>
|
||||
<xsl:when test='string-length(atom:title) > 0'>
|
||||
<xsl:value-of select='atom:title'/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
*** No Title ***
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:element>
|
||||
</h4>
|
||||
<h5 class='related'>
|
||||
💡️
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:value-of select='atom:link[@rel="alternate" and @type="x-scheme-handler/xmpp"]/@href'/>
|
||||
</xsl:attribute>
|
||||
PubSub
|
||||
</xsl:element>
|
||||
​ 
|
||||
💬
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:value-of select='atom:link[@rel="related" and @type="text/html"]/@href'/>
|
||||
</xsl:attribute>
|
||||
People
|
||||
</xsl:element>
|
||||
</h5>
|
||||
<!-- entry content -->
|
||||
<p class='summary'>
|
||||
<xsl:value-of select='atom:summary'/>
|
||||
</p>
|
||||
<!-- entry tags -->
|
||||
<xsl:if test='atom:category/@term'>
|
||||
<div class='details'>
|
||||
<xsl:for-each select='atom:category'>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
?tags=<xsl:value-of select='@term'/>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select='@term'/>
|
||||
</xsl:element>
|
||||
 
|
||||
</xsl:for-each>
|
||||
<h5 class='date'>
|
||||
<!-- entry date -->
|
||||
<xsl:choose>
|
||||
<xsl:when test='atom:updated'>
|
||||
<xsl:attribute name='class'>
|
||||
<xsl:text>updated</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select='atom:updated'/>
|
||||
</xsl:when>
|
||||
<xsl:when test='atom:published'>
|
||||
<xsl:attribute name='class'>
|
||||
<xsl:text>published</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select='atom:published'/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<h4 class='warning atom1 published'></h4>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</h5>
|
||||
<!-- entry author -->
|
||||
<h5 class='author'>
|
||||
<xsl:choose>
|
||||
<xsl:when test='atom:author/atom:email'>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:text>mailto:</xsl:text>
|
||||
<xsl:value-of select='atom:author/atom:email'/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='title'>
|
||||
<xsl:text>Send an Email to </xsl:text>
|
||||
<xsl:value-of select='atom:author/atom:email'/>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select='atom:author/atom:name'/>
|
||||
</xsl:element>
|
||||
</xsl:when>
|
||||
<xsl:when test='atom:author/atom:uri'>
|
||||
<xsl:element name='a'>
|
||||
<xsl:attribute name='href'>
|
||||
<xsl:value-of select='atom:author/atom:uri'/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name='title'>
|
||||
<xsl:value-of select='atom:author/atom:summary'/>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select='atom:author/atom:name'/>
|
||||
</xsl:element>
|
||||
</xsl:when>
|
||||
<xsl:when test='atom:author/atom:name'>
|
||||
<xsl:text>By </xsl:text>
|
||||
<xsl:value-of select='atom:author/atom:name'/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</h5>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</article>
|
||||
<!-- entry id -->
|
||||
<xsl:if test='not(atom:id)'>
|
||||
<div class='warning atom1 id'>No entry ID</div>
|
||||
</xsl:if>
|
||||
</dd>
|
||||
</xsl:for-each>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<dd>
|
||||
<div class='entry'>
|
||||
<h3 class='title'>
|
||||
<a href='javascript:alert("Please check that the mother PubSub node is populated with content.")'>
|
||||
No content
|
||||
</a>
|
||||
</h3>
|
||||
<h4>This entry is empty</h4>
|
||||
<div class='content'>Please check that the mother PubSub node is populated with content.</div>
|
||||
</div>
|
||||
</dd>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<dd>
|
||||
<article class='title'>
|
||||
<h4 class='title'>
|
||||
<a href='/help/feeds'>
|
||||
About Blasta Feeds
|
||||
</a>
|
||||
</h4>
|
||||
<h5 class='related'>
|
||||
 
|
||||
<img alt='💡'
|
||||
height='16'
|
||||
src='/graphic/xmpp.svg'
|
||||
width='16' />
|
||||
 
|
||||
<a href='/help/about/xmpp/pubsub'>XMPP</a>
|
||||
 
|
||||
<img alt='⚛'
|
||||
class='enlarge'
|
||||
height='16'
|
||||
src='/graphic/syndicate.svg'
|
||||
width='16' />
|
||||
 
|
||||
<a href='/help/syndication'>Syndication</a>
|
||||
</h5>
|
||||
<p>
|
||||
This is a concise introduction to the syndication
|
||||
technology. <b>Please, read it.</b>
|
||||
</p>
|
||||
<p>
|
||||
This an Atom document which can also be viewed
|
||||
with a Syndication Feed Reader (also referred to
|
||||
as News Reader or RSS Reader) which provides
|
||||
automated news updates and notifications on
|
||||
desktop and mobile.
|
||||
<a href='/help/syndication#software'>Click
|
||||
here</a> for a selection of software and pick
|
||||
the ones that would fit to you best!
|
||||
</p>
|
||||
<p>
|
||||
This ASF (Atom Syndication Format) document is
|
||||
conveyed as an XHTML document. This document was
|
||||
produced by an XSLT <a
|
||||
href='stylesheet/stylesheet.xsl'>stylesheet</a>.
|
||||
</p>
|
||||
<p>
|
||||
XSLT is a powerful technology which transforms
|
||||
XML documents into HTML, JSON, PDF, Text, XHTML,
|
||||
and (modified) XML documents;
|
||||
<a href='https://www.w3.org/Style/XSL/'>Learn
|
||||
more</a> about The Extensible Stylesheet
|
||||
Language Family (XSL).
|
||||
</p>
|
||||
<div class='details'>
|
||||
<a href='?tags=brand:atompub'>brand:atompub </a>
|
||||
<a href='?tags=brand:atomsub'>brand:atomsub </a>
|
||||
<a href='?tags=brand:pubsub'>brand:pubsub </a>
|
||||
<a href='?tags=code:xslt'>code:xslt </a>
|
||||
<a href='?tags=filetype:atom'>filetype:atom </a>
|
||||
<a href='?tags=filetype:rss'>filetype:rss </a>
|
||||
<a href='?tags=filetype:xml'>filetype:xml </a>
|
||||
<a href='?tags=software:libervia'>software:libervia </a>
|
||||
<a href='?tags=software:movim'>software:movim </a>
|
||||
<a href='?tags=software:reeder'>software:reeder </a>
|
||||
<a href='?tags=niche:syndication'>niche:syndication</a>
|
||||
<h5 class='updated'>2024-08-22T17:09:04+03:00</h5>
|
||||
<h5 class='author'>
|
||||
<a href='/jid/sch@pimux.de'>sch@pimux.de</a>
|
||||
</h5>
|
||||
</div>
|
||||
</article>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<dl>
|
||||
<dd>
|
||||
<img src='/graphic/blasta.svg' alt='logo'/>
|
||||
<a href='/'>
|
||||
Blasta
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://joinjabber.org'
|
||||
title='An Inclusive Space On The Jabber Network.'>
|
||||
JoinJabber
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://libervia.org'
|
||||
title='The Universal Communication Ecosystem.'>
|
||||
Libervia
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://join.movim.eu'
|
||||
title='The Social Platform Shaped For Your Community.'>
|
||||
Movim
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://git.xmpp-it.net/sch/Rivista'
|
||||
title='A Journal Publisher And Browser For XMPP.'>
|
||||
Rivista
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://github.com/SeveFP/Reeder'
|
||||
title='An XMPP-Based Feed Reader.'>
|
||||
Reeder
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://modernxmpp.org'
|
||||
title='A Project To Improve The Quality Of User-To-User Messaging Applications That Use XMPP.'>
|
||||
Modern
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://xmpp.org'
|
||||
title='The Universal Messaging Standard.'>
|
||||
XMPP
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href='https://xmpp.org/extensions/xep-0060.html'
|
||||
title='XEP-0060: Publish-Subscribe.'>
|
||||
PubSub
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
49
template/browse.atom
Normal file
49
template/browse.atom
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="stylesheet/stylesheet.xsl"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<generator uri="https://git.xmpp-it.net/sch/Blasta" version="0.1">Blasta</generator>
|
||||
<icon>/graphic/blasta.svg</icon>
|
||||
<link href="{{request.url}}"
|
||||
rel="self"
|
||||
type="text/html" />
|
||||
<link href="{{request.url.__str__().replace('?mode=feed', '')}}"
|
||||
rel="alternate"
|
||||
type="text/html" />
|
||||
<link href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}"
|
||||
rel="alternate"
|
||||
type="x-scheme-handler/xmpp" />
|
||||
<logo>/graphic/blasta.svg</logo>
|
||||
<subtitle type="text">{{description}}</subtitle>
|
||||
<title type="text">Blasta / {{path}}</title>
|
||||
<updated>{{entries[0]['updated']}}</updated>
|
||||
{% if entries %}
|
||||
{% for entry in entries %}
|
||||
<entry>
|
||||
<author>
|
||||
<name>{{entry['name']}}</name>
|
||||
<uri>/jid/{{entry['jid']}}</uri>
|
||||
<uri>xmpp:{{entry['jid']}}</uri>
|
||||
<xmpp>{{entry['jid']}}</xmpp>
|
||||
</author>
|
||||
<id>{{entry['url_hash']}}</id>
|
||||
<link href="{{entry['link']}}"
|
||||
rel="alternate" />
|
||||
<link href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node=hash:{{entry['url_hash']}}"
|
||||
rel="alternate"
|
||||
type="x-scheme-handler/xmpp" />
|
||||
<link href="/url/{{entry['url_hash']}}"
|
||||
rel="related"
|
||||
type="text/html" />
|
||||
<published>{{entry['published']}}</published>
|
||||
<summary type="text">{{entry['summary']}}</summary>
|
||||
<title>{{entry['title']}}</title>
|
||||
<updated>{{entry['updated']}}</updated>
|
||||
{% if entry['tags'] | length > 0 %}
|
||||
{% for tag in entry['tags'] %}
|
||||
<category term="{{tag}}" />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</entry>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</feed>
|
|
@ -11,8 +11,8 @@
|
|||
<link rel="stylesheet" type="text/css" media="screen"
|
||||
href="/stylesheet/stylesheet.css" />
|
||||
<link rel="alternate" type="application/atom+xml"
|
||||
title="Follow updates on /{{syndicate}}{% if param_tags %} for Tag: #{{param_tags}}{% endif %}{% if param_url %} for URL: {{param_url}}{% endif %}{% if param_hash %} for hash: {{param_hash}}{% endif %}"
|
||||
href="/{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}" />
|
||||
title="Follow updates on /{% if jid %}jid/{% endif %}{{syndicate}}{% if param_tags %} for Tag: #{{param_tags}}{% endif %}{% if param_url %} for URL: {{param_url}}{% endif %}{% if param_hash %} for hash: {{param_hash}}{% endif %}"
|
||||
href="/{% if jid %}jid/{% endif %}{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}" />
|
||||
<link rel="alternate" type="application/atom+xml"
|
||||
title="Subscribe to PubSub /{{syndicate}}{% if param_tags %} for Tag: #{{param_tags}}{% endif %}{% if param_url %} for URL: {{param_url}}{% endif %}{% if param_hash %} for hash: {{param_hash}}{% endif %}"
|
||||
href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}" />
|
||||
|
@ -227,7 +227,7 @@
|
|||
​ 
|
||||
and
|
||||
<img alt="⚛" class="enlarge" src="/graphic/syndicate.svg" width="16" height="16"/>
|
||||
<a href="/{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}">
|
||||
<a href="/{% if jid %}jid/{% endif %}{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}">
|
||||
RSS
|
||||
<!-- img src="/graphic/atom.svg" width="36" height="14" alt="Atom"/ -->
|
||||
</a>
|
Loading…
Reference in a new issue