diff options
author | Kevin Chabowski <kevin@kch42.de> | 2012-03-03 14:25:39 +0100 |
---|---|---|
committer | Kevin Chabowski <kevin@kch42.de> | 2012-03-03 14:25:39 +0100 |
commit | 6d1ef4d36ddc545acb1d43386194eaa635c0db39 (patch) | |
tree | df66c4015d03bf7901cf435045fd6459510d1652 | |
download | atom_feed-6d1ef4d36ddc545acb1d43386194eaa635c0db39.tar.gz atom_feed-6d1ef4d36ddc545acb1d43386194eaa635c0db39.tar.bz2 atom_feed-6d1ef4d36ddc545acb1d43386194eaa635c0db39.zip |
Initial commit.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CONTRIBUTORS | 6 | ||||
-rw-r--r-- | COPYING | 18 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | build.sh | 5 | ||||
-rw-r--r-- | help.html | 20 | ||||
-rw-r--r-- | plugin.php | 198 | ||||
-rw-r--r-- | tpls/backend.html | 16 | ||||
-rw-r--r-- | tpls/feed.xml | 51 | ||||
-rw-r--r-- | tpls/tpls.zip | bin | 0 -> 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> @@ -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><ste:atom_feed /></code>.</p> +<p>Put this tag in your <code><head /></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 Binary files differnew file mode 100644 index 0000000..0ee4579 --- /dev/null +++ b/tpls/tpls.zip |