aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2012-03-03 14:25:39 +0100
committerKevin Chabowski <kevin@kch42.de>2012-03-03 14:25:39 +0100
commit6d1ef4d36ddc545acb1d43386194eaa635c0db39 (patch)
treedf66c4015d03bf7901cf435045fd6459510d1652
downloadatom_feed-6d1ef4d36ddc545acb1d43386194eaa635c0db39.tar.gz
atom_feed-6d1ef4d36ddc545acb1d43386194eaa635c0db39.tar.bz2
atom_feed-6d1ef4d36ddc545acb1d43386194eaa635c0db39.zip
Initial commit.
-rw-r--r--.gitignore1
-rw-r--r--CONTRIBUTORS6
-rw-r--r--COPYING18
-rw-r--r--README.md4
-rwxr-xr-xbuild.sh5
-rw-r--r--help.html20
-rw-r--r--plugin.php198
-rw-r--r--tpls/backend.html16
-rw-r--r--tpls/feed.xml51
-rw-r--r--tpls/tpls.zipbin0 -> 1410 bytes
10 files changed, 319 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bdebf46
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+atom_feed.rpk \ No newline at end of file
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 0000000..cb16107
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,6 @@
+People who have worked on atom_feed
+===================================
+
+If you modified something, feel free to append your name to this list.
+
+* Kevin Chabowski <kevin@kch42.de>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..96c0843
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,18 @@
+atom_feed: Copyright (c) 2012 The Ratatöskr Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4c34b0b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+atom_feed
+=========
+
+A Plugin for Ratatöskr to provide Atom feeds. \ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..24553ac
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+rm -f tpls/*~
+
+r7r-plugin-packer --output=atom_feed.rpk --codefile=plugin.php --classname=atom_feed --pluginname=atom_feed --author='The Ratatöskr Team' --versiontext="0.5" --versioncount=3 --api=5 --shortdesc="Power up your website with some Atom Feeds!" --helpfile=help.html --licensefile=COPYING --tpldir=tpls
diff --git a/help.html b/help.html
new file mode 100644
index 0000000..636783f
--- /dev/null
+++ b/help.html
@@ -0,0 +1,20 @@
+<h2>Atom Feed</h2>
+
+<p>Power up your website with some Atom Feeds!</p>
+
+<h3>Configuration</h3>
+
+<p>There are some details you can (and should) configure for your feeds.</p>
+
+<p>There is a backend page called "Atom Feed" in the Plugins menu. You can configure...</p>
+<ul>
+ <li>...the title of your feeds (should be your page's name)</li>
+ <li>...the URL path (the virtual directory of your website where the feeds live in, you usually do not have to modify this)</li>
+ <li>...Some informations about the default author (Name must be set, email and uri are optional)</li>
+ <li>...the unique ID of your feeds (you should not modify this, unless you really know what you are doing)</li>
+</ul>
+
+<h3>Embedding feeds in your template</h3>
+
+<p>This plugin will give you a new STE-Tag: <code>&lt;ste:atom_feed /&gt;</code>.</p>
+<p>Put this tag in your <code>&lt;head /&gt;</code> section and it will generate links to your feeds.</p>
diff --git a/plugin.php b/plugin.php
new file mode 100644
index 0000000..21abfa0
--- /dev/null
+++ b/plugin.php
@@ -0,0 +1,198 @@
+<?php
+
+class atom_feed extends RatatoeskrPlugin
+{
+ private $config;
+ private $config_modified;
+
+ public function pluginpage(&$data, $url_now, &$url_next)
+ {
+ $this->prepare_backend_pluginpage();
+
+ $url_next = array();
+
+ if(isset($_POST["save_config"]))
+ {
+ if(preg_match("/^[a-zA-Z0-9\\-_]+\$/", $_POST["path"]) == 0)
+ $this->ste->vars["error"] = "Invalid URL Path. Must be at least one character long and may only consist of: a-z, A-Z 0-9 - _";
+ elseif(empty($_POST["author_name"]))
+ $this->ste->vars["error"] = "Author name must be set.";
+ else
+ {
+ $this->config["title"] = $_POST["title"];
+ $this->config["path"] = $_POST["path"];
+ $this->config["unique_id"] = $_POST["baseid"];
+ $this->config["author"] = array(
+ "name" => $_POST["author_name"],
+ "email" => $_POST["author_email"],
+ "uri" => $_POST["author_uri"]
+ );
+
+ $this->config_modified = True;
+
+ $this->ste->vars["success"] = "Configuration saved.";
+ }
+ }
+
+ $this->ste->vars["feed_title"] = $this->config["title"];
+ $this->ste->vars["feed_path"] = $this->config["path"];
+ $this->ste->vars["feed_baseid"] = $this->config["unique_id"];
+ $this->ste->vars["feed_author"] = $this->config["author"];
+
+ echo $this->ste->exectemplate($this->get_template_dir() . "/backend.html");
+ }
+
+ public function ste_tag_atom_feed($ste, $params, $sub)
+ {
+ global $ratatoeskr_settings;
+
+ $feeds = array(array("", "/section/" . $ratatoeskr_settings["default_section"]));
+ if(isset($ste->vars["current"]["article"]))
+ {
+ if($ste->vars["current"]["article"]["comments_allowed"])
+ $feeds[] = array("Comments", "/comments/" . $ste->vars["current"]["article"]["id"]);
+ $feeds[] = array($ste->vars["current"]["article"]["section"]["title"], "/section/" . $ste->vars["current"]["article"]["section"]["id"]);
+ }
+ elseif(isset($ste->vars["current"]["section"]) and ($ste->vars["current"]["section"]["id"] != $ratatoeskr_settings["default_section"]))
+ $feeds[] = array($ste->vars["current"]["section"]["title"], "/section/" . $ste->vars["current"]["section"]["id"]);
+
+ $feedbase = $this->config["path"];
+
+ return implode("\n", array_map(
+ function($f) use ($ste, $feedbase)
+ {
+ global $rel_path_to_root;
+ list($title, $path) = $f;
+ return "<link href=\"$rel_path_to_root/$feedbase/" . $ste->vars["language"] . "$path.xml\" type=\"application/atom+xml\" rel=\"alternate\" title=\"" . htmlesc(empty($title) ? "Sitewide" : $title) . "\" />";
+ }, $feeds));
+ }
+
+ public function feedgenerator(&$data, $url_now, &$url_next)
+ {
+ global $ratatoeskr_settings, $rel_path_to_root;
+
+ list($lang, $mode, $item_id) = $url_next;
+ $url_next = array();
+ if(substr($item_id, -4) == ".xml")
+ $item_id = substr($item_id, 0, -4) + 0;
+ else
+ $item_id += 0;
+
+ if(empty($lang) or empty($mode) or empty($item_id))
+ throw new NotFoundError();
+
+ if(($mode != "section") and ($mode != "comments"))
+ throw new NotFoundError();
+
+ if(!in_array($lang, $ratatoeskr_settings["languages"]))
+ throw new NotFoundError();
+
+ $baseurl = explode("/",self_url());
+ $baseurl = array_slice($baseurl, 0, -1);
+ foreach(explode("/", $rel_path_to_root) as $part)
+ {
+ if($part == "..")
+ $baseurl = array_slice($baseurl, 0, -1);
+ }
+ $baseurl = implode("/", $baseurl);
+
+ $this->ste->vars["xmlbase"] = self_url();
+ $this->ste->vars["baseurl"] = $baseurl;
+
+ $this->ste->vars["feed"] = array(
+ "lang" => $lang,
+ "feedpath" => urlencode($this->config["path"]),
+ "title" => "",
+ "alternate" => "",
+ "mode" => $mode,
+ "unique_id" => $this->config["unique_id"],
+ "id" => $item_id,
+ "author" => $this->config["author"],
+ "updated" => 0,
+ "entries" => array()
+ );
+
+ if($mode == "section")
+ {
+ try
+ {
+ $section = Section::by_id($item_id);
+ $articles = Article::by_multi(array("section" => $section, "onlyvisible" => True, "langavail" => $lang), "timestamp", "DESC", NULL, NULL, NULL, NULL, $_);
+ $this->ste->vars["feed"]["title"] = $section->title[$lang]->text . " - " . $this->config["title"];
+ $this->ste->vars["feed"]["alternate"] = "$baseurl/$lang/" . $section->name;
+ $this->ste->vars["feed"]["updated"] = empty($articles) ? time() : $articles[0]->timestamp;
+
+ $this->ste->vars["feed"]["entries"] = array_map(function($a) use($lang, $rel_path_to_root, $baseurl, $section) { return array(
+ "id" => $a->get_id(),
+ "title" => $a->title[$lang]->text,
+ "updated" => $a->timestamp,
+ "summary" => textprocessor_apply(str_replace("%root%", $rel_path_to_root, $a->excerpt[$lang]->text), $a->excerpt[$lang]->texttype),
+ "alternate" => "$baseurl/$lang/" . $section->name . "/" . $a->urlname
+ ); }, $articles);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+ }
+ elseif($mode == "comments")
+ {
+ try
+ {
+ $article = Article::by_id($item_id);
+ if(!isset($article->title[$lang]))
+ throw new NotFoundError();
+ $comments = $article->get_comments($lang, True);
+ usort($comments, function($a, $b) { return intcmp($a->get_timestamp(), $b->get_timestamp()); });
+
+ $this->ste->vars["feed"]["title"] = "Comments for " . $article->title[$lang]->text . " - " . $this->config["title"];
+ $this->ste->vars["feed"]["alternate"] = "$baseurl/$lang/" . $article->urlname;
+ $this->ste->vars["feed"]["updated"] = empty($comments) ? $article->timestamp : $comments[count($comments)-1]->get_timestamp();
+
+ $i = 0;
+ $this->ste->vars["feed"]["entries"] = array_map(function($c) use (&$i) { $i++; return array(
+ "id" => $c->get_id(),
+ "title" => "Comment #" . $i,
+ "updated" => $c->get_timestamp(),
+ "content" => $c->create_html(),
+ "author" => array("name" => $c->author_name)
+ ); }, $comments);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+ }
+
+ header("Content-Type: application/atom+xml; charset=UTF-8");
+ echo $this->ste->exectemplate($this->get_template_dir() . "/feed.xml");
+ }
+
+ public function init()
+ {
+ $this->config = $this->kvstorage["config"];
+ $this->config_modified = False;
+
+ $this->ste->register_tag("atom_feed", array($this, "ste_tag_atom_feed"));
+ $this->register_url_handler($this->config["path"], array($this, "feedgenerator"));
+ $this->register_backend_pluginpage("Atom Feed", array($this, "pluginpage"));
+ }
+
+ public function install()
+ {
+ $this->kvstorage["config"] = array(
+ "path" => "atom-feeds",
+ "unique_id" => uniqid("", True),
+ "author" => array("name" => "*", "email" => "", "uri" => ""),
+ "title" => "My Feed"
+ );
+ }
+
+ public function atexit()
+ {
+ if($this->config_modified)
+ $this->kvstorage["config"] = $this->config;
+ }
+}
+
+?>
diff --git a/tpls/backend.html b/tpls/backend.html
new file mode 100644
index 0000000..284b7c0
--- /dev/null
+++ b/tpls/backend.html
@@ -0,0 +1,16 @@
+<ste:load name="/systemtemplates/master.html" />
+<ste:block name="content">
+ <ste:default_error />
+ <ste:default_success />
+
+ <h2>Configure your feeds</h2>
+ <form action="$rel_path_to_pluginpage" method="POST" accept-charset="UTF-8">
+ <p><strong>Title of your feeds:</strong> <input type="text" name="title" value="<ste:escape>$feed_title</ste:escape>" /></p>
+ <p><strong>URL path:</strong> <input type="text" name="path" value="<ste:escape>$feed_path</ste:escape>" /></p>
+ <p><strong>Default author name:</strong> <input type="text" name="author_name" value="<ste:escape>$feed_author[name]</ste:escape>" /></p>
+ <p><strong>Default author email:</strong> <input type="text" name="author_email" value="<ste:escape>$feed_author[email]</ste:escape>" /></p>
+ <p><strong>Default author uri:</strong> <input type="text" name="author_uri" value="<ste:escape>$feed_author[uri]</ste:escape>" /></p>
+ <p><strong>Feed base ID (only change this, if you really know what you are doing):</strong> <input type="text" name="baseid" value="<ste:escape>$feed_baseid</ste:escape>" /></p>
+ <p><input type="submit" name="save_config" /></p>
+ </form>
+</ste:block>
diff --git a/tpls/feed.xml b/tpls/feed.xml
new file mode 100644
index 0000000..1074b88
--- /dev/null
+++ b/tpls/feed.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ste:mktag name="atom_feed_author" mandatory="var">
+ <author>
+ <name><ste:escape><ste:get var="${_tag_parameters[var]}[name]" /></ste:escape></name>
+ ?{<ste:get var="${_tag_parameters[var]}[email]" />|<email><ste:escape><ste:get var="${_tag_parameters[var]}[email]" /></ste:escape></email>|}
+ ?{<ste:get var="${_tag_parameters[var]}[uri]" />|<uri><ste:escape><ste:get var="${_tag_parameters[var]}[uri]" /></ste:escape></uri>|}
+ </author>
+</ste:mktag>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="$feed[lang]" xml:base="$xmlbase">
+ <title><ste:escape>$feed[title]</ste:escape></title>
+ <link rel="self" href="<ste:escape>$baseurl/$feed[feedpath]/$feed[lang]/$feed[mode]/$feed[id].xml</ste:escape>"/>
+ ?{$feed[alternate]|<link href="<ste:escape>$feed[alternate]</ste:escape>" />|}
+ <updated><ste:date timestamp="$feed[updated]">%Y-%m-%dT%H:%M:%SZ</ste:date></updated>
+ <ste:if>$feed[author]
+ <ste:then>
+ <ste:atom_feed_author var="feed[author]" />
+ </ste:then>
+ </ste:if>
+ <ste:set var="feed_id_root">data:,<ste:escape>$feed[unique_id]/$feed[lang]/$feed[mode]/$feed[id]</ste:escape></ste:set>
+ <id>$feed_id_root</id>
+ <generator>atom_feed plugin for Ratatöskr</generator>
+
+ <ste:foreach array="feed[entries]" value="entry">
+ <entry>
+ <id>$feed_id_root/$entry[id]</id>
+ <title><ste:escape>$entry[title]</ste:escape></title>
+ <updated><ste:date timestamp="$entry[updated]">%Y-%m-%dT%H:%M:%SZ</ste:date></updated>
+ ?{$entry[author]|<ste:atom_feed_author var="entry[author]" />|}
+ <ste:if>$entry[content]
+ <ste:then>
+ <content type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">$entry[content]</div>
+ </content>
+ </ste:then>
+ </ste:if>
+ <ste:if>$entry[summary]
+ <ste:then>
+ <summary type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">$entry[summary]</div>
+ </summary>
+ </ste:then>
+ </ste:if>
+ <ste:if>$entry[alternate]
+ <ste:then>
+ <link href="<ste:escape>$entry[alternate]</ste:escape>" />
+ </ste:then>
+ </ste:if>
+ </entry>
+ </ste:foreach>
+
+</feed>
diff --git a/tpls/tpls.zip b/tpls/tpls.zip
new file mode 100644
index 0000000..0ee4579
--- /dev/null
+++ b/tpls/tpls.zip
Binary files differ