From 6d1ef4d36ddc545acb1d43386194eaa635c0db39 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Sat, 3 Mar 2012 14:25:39 +0100 Subject: Initial commit. --- .gitignore | 1 + CONTRIBUTORS | 6 ++ COPYING | 18 +++++ README.md | 4 ++ build.sh | 5 ++ help.html | 20 ++++++ plugin.php | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tpls/backend.html | 16 +++++ tpls/feed.xml | 51 ++++++++++++++ tpls/tpls.zip | Bin 0 -> 1410 bytes 10 files changed, 319 insertions(+) create mode 100644 .gitignore create mode 100644 CONTRIBUTORS create mode 100644 COPYING create mode 100644 README.md create mode 100755 build.sh create mode 100644 help.html create mode 100644 plugin.php create mode 100644 tpls/backend.html create mode 100644 tpls/feed.xml create mode 100644 tpls/tpls.zip 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 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 @@ +

Atom Feed

+ +

Power up your website with some Atom Feeds!

+ +

Configuration

+ +

There are some details you can (and should) configure for your feeds.

+ +

There is a backend page called "Atom Feed" in the Plugins menu. You can configure...

+ + +

Embedding feeds in your template

+ +

This plugin will give you a new STE-Tag: <ste:atom_feed />.

+

Put this tag in your <head /> section and it will generate links to your feeds.

diff --git a/plugin.php b/plugin.php new file mode 100644 index 0000000..21abfa0 --- /dev/null +++ b/plugin.php @@ -0,0 +1,198 @@ +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 "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 @@ + + + + + +

Configure your feeds

+
+

Title of your feeds:

+

URL path:

+

Default author name:

+

Default author email:

+

Default author uri:

+

Feed base ID (only change this, if you really know what you are doing):

+

+
+
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 @@ + + + + + ?{||} + ?{||} + + + + <ste:escape>$feed[title]</ste:escape> + + ?{$feed[alternate]||} + %Y-%m-%dT%H:%M:%SZ + $feed[author] + + + + + data:,$feed[unique_id]/$feed[lang]/$feed[mode]/$feed[id] + $feed_id_root + atom_feed plugin for Ratatöskr + + + + $feed_id_root/$entry[id] + <ste:escape>$entry[title]</ste:escape> + %Y-%m-%dT%H:%M:%SZ + ?{$entry[author]||} + $entry[content] + + +
$entry[content]
+
+
+
+ $entry[summary] + + +
$entry[summary]
+
+
+
+ $entry[alternate] + + + + +
+
+ +
diff --git a/tpls/tpls.zip b/tpls/tpls.zip new file mode 100644 index 0000000..0ee4579 Binary files /dev/null and b/tpls/tpls.zip differ -- cgit v1.2.3-54-g00ecf