Hi,

I'd very much like to be able to list my blog posts on a daily basis (used for logging work) - rather than have the Calendar plugin return the first post only.

There was some effort to do this as detailed here.

Set arbitrary date to be used by calendar plugin

I had a quick go at doing something similar on Debian Stable (Ikiwiki 3.0) but alas my Ikiwiki fu is not strong enough.

I'm not sure how I go about swapping the link on the day number to a link to, I guess, a dynamically generated page of links?

$linkcach{"$year/$mtag/$mday"}{$p} = ${p}

and a suitable whilst loop looks to be all that's needed...

Any pointers appreciated.

A patch has been proposed in comment

This has been applied. --Joey

So I ported the original patch mentioned to the latest Debian version. Well at least the bits that matter to me. See below.

In doing so I realized that it does quite work how I imagined it would; instead of generating a dynamic page for a particular day with a list of links it actually fills in the calendar with the details of the posts (making for some ugly formatting).

I'm hoping the tag generation pages will give me a clue how to alter this into what I want.

diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm
index c7d2b7c..c931fe6 100644
--- a/IkiWiki/Plugin/calendar.pm
+++ b/IkiWiki/Plugin/calendar.pm
@@ -75,6 +75,8 @@ sub format_month (@) {   
        my %params=@_;

        my %linkcache;
+    my @list;
+    my $detail = 1;
        foreach my $p (pagespec_match_list($params{page},
                                "creation_year($params{year}) and creation_month($params{month}) and ($params{pages})",
                                # add presence dependencies to update
@@ -88,7 +90,7 @@ sub format_month (@) {   
                my $mtag  = sprintf("%02d", $month);

                # Only one posting per day is being linked to.
-               $linkcache{"$year/$mtag/$mday"} = $p;
+               $linkcache{"$year/$mtag/$mday"}{$p} = $IkiWiki::pagesources{$p};
        }

        my $pmonth = $params{month} - 1;   
@@ -219,14 +221,38 @@ EOF
                                $tag='month-calendar-day-this-day';
                        }
                        else {
-                               $tag='month-calendar-day-link';
+                               if ( $detail == 0 ) {
+                                       $tag='month-calendar-day-link';
+                               }
+                               else{
+                                       $tag='month-calendar-day';
+                               }
                        }
                        $calendar.=qq{\t\t};
-                       $calendar.=htmllink($params{page}, $params{destpage},
-                               $linkcache{$key},
-                               noimageinline => 1,
-                               linktext => $day,
-                               title => pagetitle(IkiWiki::basename($linkcache{$key})));
+                       if ( $detail == 0 ) {
+                               $calendar.=htmllink($params{page}, $params{destpage},
+                                               $linkcache{$key},
+                                               noimageinline => 1,
+                                               linktext => $day,
+                                               title => pagetitle(IkiWiki::basename($linkcache{$key})));
+                       }
+                       else {
+                               my $day_label = qq{$day};
+                               $calendar.=qq{$day_label\n};
+                               my $srcpage; my $destpage;
+                               while(($srcpage,$destpage) = each(%{$linkcache{$key}})) {
+                                       my $title = IkiWiki::basename(pagename($srcpage));
+                                       if (exists $pagestate{$srcpage}{meta}{title} ) {
+                                               $title = $pagestate{$srcpage}{meta}{title};
+                                       }  
+                                       $calendar.=qq{\t\t
}; + $calendar.=htmllink($params{page}, $params{destpage}, + pagename($destpage), + linktext => $title); + push @list, pagename($linkcache{$key}{$srcpage}); + $calendar.=qq{\t\t
}; + } + } $calendar.=qq{\n}; } else {
Comment by Matt Mon Nov 28 20:52:49 2011

To revert the changes made above it is necessary not only to switch the detail level back down but to also regenerate the side-bar index.html file

ikiwiki --setup blog.setup

should do it.

Comment by Matt Mon Nov 28 21:30:09 2011

I got to grip with things to make a patch to do this. :-)

Here it is in case of use to anyone.

From f0554c5b61e1915086d5cf071f095ff233c2590d Mon Sep 17 00:00:00 2001
From: Matt Ford 
Date: Wed, 30 Nov 2011 19:40:10 +0000
Subject: [PATCH] Patch to allow daily archival generation and link to them in
 the calendar

---
 IkiWiki/Plugin/calendar.pm   |   17 ++++++++++++++++-
 ikiwiki-calendar.in          |   34 +++++++++++++++++++++++++++++++---
 templates/calendarday.tmpl   |    5 +++++
 templates/calendarmonth.tmpl |    2 +-
 templates/calendaryear.tmpl  |    2 +-
 5 files changed, 54 insertions(+), 6 deletions(-)
 create mode 100644 templates/calendarday.tmpl

diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm
index c7d2b7c..9999c03 100644
--- a/IkiWiki/Plugin/calendar.pm
+++ b/IkiWiki/Plugin/calendar.pm
@@ -47,6 +47,13 @@ sub getsetup () {
            safe => 1,
            rebuild => 1,
        },
+       archiveday => {
+           type => "boolean",
+           example => 1,
+           description => "enable archiving on a daily basis (otherwise monthly)",
+           safe => 1,
+           rebuild => 1,
+       },
        archive_pagespec => {
            type => "pagespec",
            example => "page(posts/*) and !*/Discussion",
@@ -222,11 +229,19 @@ EOF
                $tag='month-calendar-day-link';
            }
            $calendar.=qq{\t\t};
-           $calendar.=htmllink($params{page}, $params{destpage}, 
+           if (exists $pagesources{"$archivebase/$params{year}/$params{month}/".sprintf("%02d",$day)}) {
+               $calendar.=htmllink($params{page}, $params{destpage}, 
+                       "$archivebase/$params{year}/$params{month}/".sprintf("%02d",$day),
+                       noimageinline => 1,
+                       linktext => "$day",
+                       title => "$key");
+           }else{
+               $calendar.=htmllink($params{page}, $params{destpage}, 
                $linkcache{$key},
                noimageinline => 1,
                linktext => $day,
                title => pagetitle(IkiWiki::basename($linkcache{$key})));
+           }
            $calendar.=qq{\n};
        }
        else {
diff --git a/ikiwiki-calendar.in b/ikiwiki-calendar.in
index 037ef7d..af22bc5 100755
--- a/ikiwiki-calendar.in
+++ b/ikiwiki-calendar.in
@@ -30,21 +30,44 @@ IkiWiki::checkconfig();
 my $archivebase = 'archives';
 $archivebase = $config{archivebase} if defined $config{archivebase};
 
+my $archiveday = 0;
+$archiveday = $config{archiveday} if defined $config{archiveday};
+
 if (! defined $pagespec) {
    $pagespec=$config{archive_pagespec} || "*";
 }
 
-sub writearchive ($$;$) {
+sub is_leap_year {
+   my $year=shift;
+   return ($year % 4 == 0 && (($year % 100 != 0) || $year % 400 == 0));
+}
+
+sub month_days {
+   my $month=shift;
+        my $year=shift;
+   my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$month-1];
+   if ($month == 2 && is_leap_year($year)) {
+       $days_in_month++;
+   }
+   return $days_in_month;
+}
+
+sub writearchive ($$;$;$) {
    my $template=template(shift);
    my $year=shift;
    my $month=shift;
+        my $day=shift;
 
-   my $page=defined $month ? "$year/$month" : $year;
+   my $page;
+        if (defined $year)  {$page = "$year"};
+        if (defined $month) {$page = "$year/$month"};
+        if (defined $day)   {$page = "$year/$month/$day"};
 
    my $pagefile=newpagefile("$archivebase/$page", $config{default_pageext});
    $template->param(pagespec => $pagespec);
    $template->param(year => $year);
    $template->param(month => $month) if defined $month;
+   $template->param(day => $day) if defined $day;
 
    if ($force || ! -e "$config{srcdir}/$pagefile") {
        writefile($pagefile, $config{srcdir}, $template->output);
@@ -54,8 +77,13 @@ sub writearchive ($$;$) {
 
 foreach my $y ($startyear..$endyear) {
    writearchive("calendaryear.tmpl", $y);
-   foreach my $m (qw{01 02 03 04 05 06 07 08 09 10 11 12}) {
+   foreach my $m (map {sprintf("%02d",$_)} (1..12)) {
        writearchive("calendarmonth.tmpl", $y, $m);
+       if ($archiveday ) {
+           foreach my $d (map {sprintf("%02d",$_)} (1..month_days($m,$y))) {
+               writearchive("calendarday.tmpl", $y, $m, $d);
+           }
+       }
    }
 }
 
diff --git a/templates/calendarday.tmpl b/templates/calendarday.tmpl
new file mode 100644
index 0000000..ac963b9
--- /dev/null
+++ b/templates/calendarday.tmpl
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month= year= pages=""]]
+"""]]
+
+[[!inline pages="creation_day() and creation_month() and creation_year() and " archive="yes" show=0 feeds=no reverse=yes]]
diff --git a/templates/calendarmonth.tmpl b/templates/calendarmonth.tmpl
index 23cd954..c998c16 100644
--- a/templates/calendarmonth.tmpl
+++ b/templates/calendarmonth.tmpl
@@ -2,4 +2,4 @@
 [[!calendar type=month month= year= pages=""]]
 """]]
 
-[[!inline pages="creation_month() and creation_year() and " show=0 feeds=no reverse=yes]]
+[[!inline pages="creation_month() and creation_year() and " archive="yes" show=0 feeds=no reverse=yes]]
diff --git a/templates/calendaryear.tmpl b/templates/calendaryear.tmpl
index 714bd6d..b6e33c5 100644
--- a/templates/calendaryear.tmpl
+++ b/templates/calendaryear.tmpl
@@ -1 +1 @@
-[[!calendar type=year year= pages=""]]
+[[!calendar type=year year= pages="" archive="yes"]]
-- 
1.7.7.3

:

Comment by Matt Wed Nov 30 16:42:55 2011

To be clear, this patch creates a yyyy/mm/dd file for each day, listing the posts for that day, so the calendar can link to it rather than a random single post.

While a valid solution certainly, that's a lot of added pages! Especially a high overhead for such a minor UI point as this.

Surely something interesting could be done with javascript or some other form of UI to make clicking on a day in a calendar that has multiple posts present a list of them? That would have essentially no overhead, since the calendar plugin already has a list of the posts made on a given day.

Ikiwiki already does something similar to deal with the case where a page has a great many backlinks.. It makes a UI element that, if hovered over, pops up a display of all the rest. This is done quite simply in the page.tmpl using the popup and balloon CSS classes. Calendar could also use this.

Comment by joey Tue Feb 21 13:23:00 2012

[[!tag patch]]

Hello, here is a patch that:

  • if there is a single entry in one day, does not change anything (compared to the previous version of the calendar plugin);
  • if there are several entries, when mouse passes over the day, displays a popup listing all the entries of that day.

That's all. No new pages for each day, takes as little space as it took before, and only a few lines more in the source.

The only thing I am not totally happy with is the CSS. We have to say that the text is aligned on the left (otherwise, it is aligned on the right, as is each day of the calendar), but I do not know which place is the more sensible to put that line of CSS in.

Regards,
-- Louis

diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm
index d443198..2c9ed79 100644
--- a/IkiWiki/Plugin/calendar.pm
+++ b/IkiWiki/Plugin/calendar.pm
@@ -86,8 +86,11 @@ sub format_month (@) {
        my $year  = $date[5] + 1900;
        my $mtag  = sprintf("%02d", $month);

-       # Only one posting per day is being linked to.
-       $linkcache{"$year/$mtag/$mday"} = $p;
+       # Several postings per day
+       if (! $linkcache{"$year/$mtag/$mday"}) {
+           $linkcache{"$year/$mtag/$mday"} = [];
+       }
+       push(@{$linkcache{"$year/$mtag/$mday"}}, $p);
    }

    my $pmonth = $params{month} - 1;
@@ -221,11 +224,36 @@ EOF
                $tag='month-calendar-day-link';
            }
            $calendar.=qq{\t\t<td class="$tag $downame{$wday}">};
-           $calendar.=htmllink($params{page}, $params{destpage}, 
-               $linkcache{$key},
-               noimageinline => 1,
-               linktext => $day,
-               title => pagetitle(IkiWiki::basename($linkcache{$key})));
+           if ( scalar(@{$linkcache{$key}}) == 1) {
+               # Only one posting on this page
+               my $page = $linkcache{$key}[0];
+               $calendar.=htmllink($params{page}, $params{destpage}, 
+                   $page,
+                   noimageinline => 1,
+                   linktext => $day,
+                   title => pagetitle(IkiWiki::basename($page)));
+           } else {
+               $calendar.=qq{<div class='popup'>$day<div class='balloon'>};
+               # Several postings on this page
+               $calendar.=qq{<ul>};
+               foreach my $page (@{$linkcache{$key}}) {
+                   $calendar.= qq{\n\t\t\t<li>};
+                   my $title;
+                   if (exists $pagestate{$page}{meta}{title}) {
+                       $title = "$pagestate{$page}{meta}{title}";
+                   } else {
+                       $title = pagetitle(IkiWiki::basename($page));
+                   }
+                   $calendar.=htmllink($params{page}, $params{destpage}, 
+                       $page,
+                       noimageinline => 1,
+                       linktext => $title,
+                       title => $title);
+                   $calendar.= '</li>';
+               }
+               $calendar.=qq{\n\t\t</ul>};
+               $calendar.=qq{</div></div>};
+           }
            $calendar.=qq{</td>\n};
        }
        else {
diff --git a/doc/style.css b/doc/style.css
old mode 100644
new mode 100755
index 6e2afce..4149229
--- a/doc/style.css
+++ b/doc/style.css
@@ -316,6 +316,7 @@ div.progress-done {
 .popup .paren,
 .popup .expand {
    display: none;
+   text-align: left;
 }
 .popup:hover .balloon,
 .popup:focus .balloon {
Comment by spalax Thu Jun 7 20:56:06 2012