summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess <joey@kodama.kitenet.net>2008-10-17 20:47:32 -0400
committerJoey Hess <joey@kodama.kitenet.net>2008-10-17 20:47:32 -0400
commit7390a7a0721d9985c88efec1fd0e3a19d0368c82 (patch)
tree5573d9a86849bb3d180ad26132e8f1abf6fdd53c
parent9a62836d288fbced42b04a172baf52063ef71c61 (diff)
relativedate: New javascript-alicious plugin that makes all dates display relative, in a very nice way, if I say so myself.
-rw-r--r--IkiWiki/Plugin/inline.pm2
-rw-r--r--IkiWiki/Plugin/relativedate.pm41
-rw-r--r--IkiWiki/Render.pm2
-rw-r--r--debian/changelog2
-rw-r--r--doc/plugins/ddate.mdwn1
-rw-r--r--doc/plugins/prettydate.mdwn2
-rw-r--r--doc/plugins/relativedate.mdwn16
-rw-r--r--doc/plugins/type/date.mdwn1
-rw-r--r--po/ikiwiki.pot32
-rw-r--r--templates/inlinepage.tmpl8
-rw-r--r--templates/page.tmpl14
-rw-r--r--underlays/javascript/relativedate.js70
12 files changed, 163 insertions, 28 deletions
diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
index 6d88c2f15..536d7cd02 100644
--- a/IkiWiki/Plugin/inline.pm
+++ b/IkiWiki/Plugin/inline.pm
@@ -316,7 +316,9 @@ sub preprocess_inline (@) { #{{{
$template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage}));
$template->param(title => pagetitle(basename($page)));
$template->param(ctime => displaytime($pagectime{$page}, $params{timeformat}));
+ $template->param(ctime_raw => scalar localtime($pagectime{$page}));
$template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat}));
+ $template->param(mtime_raw => scalar localtime($pagemtime{$page}));
$template->param(first => 1) if $page eq $list[0];
$template->param(last => 1) if $page eq $list[$#list];
diff --git a/IkiWiki/Plugin/relativedate.pm b/IkiWiki/Plugin/relativedate.pm
new file mode 100644
index 000000000..99265676b
--- /dev/null
+++ b/IkiWiki/Plugin/relativedate.pm
@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::relativedate;
+
+use warnings;
+use strict;
+use IkiWiki 2.00;
+
+sub import { #{{{
+ add_underlay("javascript");
+ hook(type => "format", id => "relativedate", call => \&format);
+} # }}}
+
+sub getsetup () { #{{{
+ return
+ plugin => {
+ safe => 1,
+ rebuild => 1,
+ },
+} #}}}
+
+sub format (@) { #{{{
+ my %params=@_;
+
+ if (! ($params{content}=~s!^(<body>)!$1.include_javascript($params{page})!em)) {
+ # no </body> tag, probably in preview mode
+ $params{content}=include_javascript($params{page}, 1).$params{content};
+ }
+ return $params{content};
+} # }}}
+
+sub include_javascript ($;$) { #{{{
+ my $page=shift;
+ my $absolute=shift;
+
+ return '<script src="'.urlto("ikiwiki.js", $page, $absolute).
+ '" type="text/javascript" charset="utf-8"></script>'."\n".
+ '<script src="'.urlto("relativedate.js", $page, $absolute).
+ '" type="text/javascript" charset="utf-8"></script>';
+} #}}}
+
+1
diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
index bc997ffb0..8385c1aff 100644
--- a/IkiWiki/Render.pm
+++ b/IkiWiki/Render.pm
@@ -109,7 +109,9 @@ sub genpage ($$) { #{{{
backlinks => $backlinks,
more_backlinks => $more_backlinks,
mtime => displaytime($pagemtime{$page}),
+ mtime_raw => scalar localtime($pagemtime{$page}),
ctime => displaytime($pagectime{$page}),
+ ctime_raw => scalar localtime($pagectime{$page}),
baseurl => baseurl($page),
);
diff --git a/debian/changelog b/debian/changelog
index 66d108e9e..908eb1f53 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,8 @@ ikiwiki (2.68) UNRELEASED; urgency=low
code.
* toggle: Stop embedding the full toggle code on each page using it, and
move it to toggle.js in the javascript underlay.
+ * relativedate: New javascript-alicious plugin that makes all dates display
+ relative, in a very nice way, if I say so myself.
-- Joey Hess <joeyh@debian.org> Fri, 17 Oct 2008 20:11:02 -0400
diff --git a/doc/plugins/ddate.mdwn b/doc/plugins/ddate.mdwn
index e82760d88..741606a6e 100644
--- a/doc/plugins/ddate.mdwn
+++ b/doc/plugins/ddate.mdwn
@@ -1,5 +1,6 @@
[[!template id=plugin name=ddate author="[[Joey]]"]]
[[!tag type/fun]]
+[[!tag type/date]]
Enables use of Discordian dates. `--timeformat` can be used to change
the date format; see `ddate(1)`.
diff --git a/doc/plugins/prettydate.mdwn b/doc/plugins/prettydate.mdwn
index 9a67f5dca..11ad4252f 100644
--- a/doc/plugins/prettydate.mdwn
+++ b/doc/plugins/prettydate.mdwn
@@ -1,5 +1,5 @@
[[!template id=plugin name=prettydate author="[[Joey]]"]]
-[[!tag type/format]]
+[[!tag type/date]]
Enabling this plugin changes the dates displayed on pages in the wiki to
a format that is nice and easy to read. Examples: "late Wednesday evening,
diff --git a/doc/plugins/relativedate.mdwn b/doc/plugins/relativedate.mdwn
new file mode 100644
index 000000000..ecbdf68bf
--- /dev/null
+++ b/doc/plugins/relativedate.mdwn
@@ -0,0 +1,16 @@
+[[!template id=plugin name=prettydate author="[[Joey]]"]]
+[[!tag type/date]]
+
+This plugin lets dates be displayed in relative form. Examples: "2 days ago",
+"1 month and 3 days ago", "30 minutes ago". Hovering over the date will
+cause a tooltip to pop up with the absolute date.
+
+This only works in browsers with javascript enabled; other browsers will
+show the absolute date instead. Also, this plugin can be used with other
+plugins like [[prettydate]] that change how the absolute date is displayed.
+
+If this plugin is enabled, you may also add relative dates to pages in the
+wiki, by using html elements in the "date" class. For example, this will
+display as a relative date:
+
+ <span class="date">Fri Oct 17 18:36:13 EDT 2008</span>
diff --git a/doc/plugins/type/date.mdwn b/doc/plugins/type/date.mdwn
new file mode 100644
index 000000000..eae1226da
--- /dev/null
+++ b/doc/plugins/type/date.mdwn
@@ -0,0 +1 @@
+These plugins control how ikiwiki displays dates.
diff --git a/po/ikiwiki.pot b/po/ikiwiki.pot
index 6853df153..2d213a799 100644
--- a/po/ikiwiki.pot
+++ b/po/ikiwiki.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-10-17 20:11-0400\n"
+"POT-Creation-Date: 2008-10-17 20:39-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -172,9 +172,9 @@ msgid "automatic index generation"
msgstr ""
#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:327 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/inline.pm:329 ../IkiWiki/Plugin/opendiscussion.pm:26
#: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
-#: ../IkiWiki/Render.pm:149
+#: ../IkiWiki/Render.pm:151
msgid "discussion"
msgstr ""
@@ -318,11 +318,11 @@ msgstr ""
msgid "nonexistant template %s"
msgstr ""
-#: ../IkiWiki/Plugin/inline.pm:335 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:337 ../IkiWiki/Render.pm:83
msgid "Discussion"
msgstr ""
-#: ../IkiWiki/Plugin/inline.pm:572
+#: ../IkiWiki/Plugin/inline.pm:574
msgid "RPC::XML::Client not found, not pinging"
msgstr ""
@@ -780,59 +780,59 @@ msgstr ""
msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
msgstr ""
-#: ../IkiWiki/Render.pm:253
+#: ../IkiWiki/Render.pm:255
#, perl-format
msgid ""
"symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to "
"allow this"
msgstr ""
-#: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302
+#: ../IkiWiki/Render.pm:279 ../IkiWiki/Render.pm:304
#, perl-format
msgid "skipping bad filename %s"
msgstr ""
-#: ../IkiWiki/Render.pm:284
+#: ../IkiWiki/Render.pm:286
#, perl-format
msgid "%s has multiple possible source pages"
msgstr ""
-#: ../IkiWiki/Render.pm:360
+#: ../IkiWiki/Render.pm:362
#, perl-format
msgid "removing old page %s"
msgstr ""
-#: ../IkiWiki/Render.pm:400
+#: ../IkiWiki/Render.pm:402
#, perl-format
msgid "scanning %s"
msgstr ""
-#: ../IkiWiki/Render.pm:405
+#: ../IkiWiki/Render.pm:407
#, perl-format
msgid "rendering %s"
msgstr ""
-#: ../IkiWiki/Render.pm:426
+#: ../IkiWiki/Render.pm:428
#, perl-format
msgid "rendering %s, which links to %s"
msgstr ""
-#: ../IkiWiki/Render.pm:447
+#: ../IkiWiki/Render.pm:449
#, perl-format
msgid "rendering %s, which depends on %s"
msgstr ""
-#: ../IkiWiki/Render.pm:486
+#: ../IkiWiki/Render.pm:488
#, perl-format
msgid "rendering %s, to update its backlinks"
msgstr ""
-#: ../IkiWiki/Render.pm:498
+#: ../IkiWiki/Render.pm:500
#, perl-format
msgid "removing %s, no longer rendered by %s"
msgstr ""
-#: ../IkiWiki/Render.pm:522
+#: ../IkiWiki/Render.pm:524
#, perl-format
msgid "ikiwiki: cannot render %s"
msgstr ""
diff --git a/templates/inlinepage.tmpl b/templates/inlinepage.tmpl
index ffcb897a8..3f640fcdd 100644
--- a/templates/inlinepage.tmpl
+++ b/templates/inlinepage.tmpl
@@ -5,9 +5,9 @@
<TMPL_IF NAME="AUTHOR">
<span class="author">
<TMPL_IF NAME="AUTHORURL">
-<a href="<TMPL_VAR NAME=AUTHORURL>"><TMPL_VAR NAME=AUTHOR></a>
+<a href="<TMPL_VAR AUTHORURL>"><TMPL_VAR AUTHOR></a>
<TMPL_ELSE>
-<TMPL_VAR NAME=AUTHOR>
+<TMPL_VAR AUTHOR>
</TMPL_IF>
</span>
</TMPL_IF>
@@ -28,14 +28,14 @@
<div class="inlinefooter">
<span class="pagedate">
-Posted <TMPL_VAR CTIME>
+Posted <span class="date" title="<TMPL_VAR CTIME_RAW>"><TMPL_VAR CTIME></span>
</span>
<TMPL_IF NAME="TAGS">
<span class="tags">
Tags:
<TMPL_LOOP NAME="TAGS">
-<TMPL_VAR NAME=LINK>
+<TMPL_VAR LINK>
</TMPL_LOOP>
</span>
</TMPL_IF>
diff --git a/templates/page.tmpl b/templates/page.tmpl
index f2f9c34cc..7456e9e41 100644
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -22,7 +22,7 @@
<span>
<span class="parentlinks">
<TMPL_LOOP NAME="PARENTLINKS">
-<a href="<TMPL_VAR NAME=URL>"><TMPL_VAR NAME=PAGE></a>/
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/
</TMPL_LOOP>
</span>
<span class="title">
@@ -74,7 +74,7 @@
<div class="tags">
Tags:
<TMPL_LOOP NAME="TAGS">
-<TMPL_VAR NAME=LINK>
+<TMPL_VAR LINK>
</TMPL_LOOP>
</div>
</TMPL_IF>
@@ -83,13 +83,13 @@ Tags:
<div id="backlinks">
Links:
<TMPL_LOOP NAME="BACKLINKS">
-<a href="<TMPL_VAR NAME=URL>"><TMPL_VAR NAME=PAGE></a>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
</TMPL_LOOP>
<TMPL_IF NAME="MORE_BACKLINKS">
<span class="popup">...
<span class="balloon">
<TMPL_LOOP NAME="MORE_BACKLINKS">
-<a href="<TMPL_VAR NAME=URL>"><TMPL_VAR NAME=PAGE></a>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
</TMPL_LOOP>
</span>
</span>
@@ -112,13 +112,13 @@ License: <TMPL_VAR LICENSE>
</TMPL_IF>
<div class="pagedate">
-Last edited <TMPL_VAR NAME=MTIME>
-<!-- Created <TMPL_VAR NAME=CTIME> -->
+Last edited <span class="date" title="<TMPL_VAR MTIME_RAW>"><TMPL_VAR MTIME></span>
+<!-- Created <TMPL_VAR CTIME> -->
</div>
</div><!-- #pageinfo -->
<TMPL_IF EXTRAFOOTER><TMPL_VAR EXTRAFOOTER></TMPL_IF>
-<!-- from <TMPL_VAR NAME=WIKINAME> -->
+<!-- from <TMPL_VAR WIKINAME> -->
</div><!-- .pagefooter #footer -->
</body>
diff --git a/underlays/javascript/relativedate.js b/underlays/javascript/relativedate.js
new file mode 100644
index 000000000..c5e62b3cc
--- /dev/null
+++ b/underlays/javascript/relativedate.js
@@ -0,0 +1,70 @@
+// Causes html elements in the 'date' and 'pagedate' classes to be displayed
+// as relative dates. The date is parsed from the title attribute, or from
+// the element content.
+
+var dateElements;
+
+hook("onload", getDates);
+
+function getDates() {
+ dateElements = getElementsByClass('date');
+ for (var i = 0; i < dateElements.length; i++) {
+ var elt = dateElements[i];
+ var title = elt.attributes.title;
+ var d = new Date(title ? title.value : elt.innerHTML);
+ if (! isNaN(d)) {
+ dateElements[i].date=d;
+ elt.title=elt.innerHTML;
+ }
+ }
+
+ showDates();
+}
+
+function showDates() {
+ for (var i = 0; i < dateElements.length; i++) {
+ var elt = dateElements[i];
+ var d = elt.date;
+ if (! isNaN(d)) {
+ elt.innerHTML=relativeDate(d);
+ }
+ }
+ setTimeout(showDates,30000); // keep updating every 30s
+}
+
+var timeUnits = new Array;
+timeUnits['minute'] = 60;
+timeUnits['hour'] = timeUnits['minute'] * 60;
+timeUnits['day'] = timeUnits['hour'] * 24;
+timeUnits['month'] = timeUnits['day'] * 30;
+timeUnits['year'] = timeUnits['day'] * 364;
+var timeUnitOrder = ['year', 'month', 'day', 'hour', 'minute'];
+
+function relativeDate(date) {
+ var now = new Date();
+ var offset = date.getTime() - now.getTime();
+ var seconds = Math.round(Math.abs(offset) / 1000);
+
+ var ret = "";
+ var shown = 0;
+ for (i = 0; i < timeUnitOrder.length; i++) {
+ var unit = timeUnitOrder[i];
+ if (seconds >= timeUnits[unit]) {
+ var num = Math.floor(seconds / timeUnits[unit]);
+ seconds -= num * timeUnits[unit];
+ if (ret)
+ ret += "and ";
+ ret += num + " " + unit + (num > 1 ? "s" : "") + " ";
+
+ if (++shown == 2)
+ break;
+ }
+ else if (shown)
+ break;
+ }
+
+ if (! ret)
+ ret = "less than a minute "
+
+ return ret + (offset < 0 ? "ago" : "from now");
+}