diff options
| -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.zipBinary files differ new file mode 100644 index 0000000..0ee4579 --- /dev/null +++ b/tpls/tpls.zip | 
