From 07f2f3c30a6e0bc811e436925dfdfcf5befdecb7 Mon Sep 17 00:00:00 2001
From: "David A. Madore" <david+git@madore.org>
Date: Sat, 12 Nov 2011 14:33:35 +0100
Subject: Entry single pages: handle permalinks gracefully, populate with
 attribute.

* A single page is generated from the single-page attribute on <entry>
  element (stored in database as do_single_page).

* Permalink refers to the single page.  Same from weblog index.  Other
  links are subject to debate (e.g., what about internal links? now we
  link to single page when link has a supplement part, but this is
  debatable).
---
 org/madore/damlengine/TodoEntryElement.java        | 14 ++++++--
 .../damlengine/TodoWeblogIndexSelectElement.java   |  8 +++--
 org/madore/damlengine/TodoWrefAttr.java            | 37 ++++++++++++++--------
 org/madore/damlengine/WeblogPopulate.java          | 37 ++++++++++++----------
 org/madore/damlengine/WeblogRSS.java               | 19 +++++++----
 org/madore/damlengine/WeblogSummary.java           | 10 ++++--
 org/madore/damlengine/weblog-cat-template.daml     |  2 ++
 org/madore/damlengine/weblog-database.sql          |  5 +--
 org/madore/damlengine/weblog-month-template.daml   |  2 ++
 org/madore/damlengine/weblog-recent-template.daml  |  2 ++
 org/madore/damlengine/weblog-single-template.daml  |  4 +--
 11 files changed, 92 insertions(+), 48 deletions(-)

diff --git a/org/madore/damlengine/TodoEntryElement.java b/org/madore/damlengine/TodoEntryElement.java
index c42943c..712e121 100644
--- a/org/madore/damlengine/TodoEntryElement.java
+++ b/org/madore/damlengine/TodoEntryElement.java
@@ -46,6 +46,7 @@ public final class TodoEntryElement extends TodoDefaultElement {
 	String entryDayStr = entryDateMatcher.group(3);
 	String entryDowStr = node.getAttributeNS(null, "day_of_week");
 	String entryCatStr = node.getAttributeNS(null, "cat");
+	String entryDoSinglePageStr = node.getAttributeNS(null, "single-page");
 	String entryCdateStr = node.getAttributeNS(null, "cdate");
 	ArrayList<String> entryCatList;
 	if ( entryCatStr.equals("") ) {
@@ -78,9 +79,16 @@ public final class TodoEntryElement extends TodoDefaultElement {
 	header.appendChild(ctx.doc.createTextNode("\n"));
 
 	Element permalink = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "a");
-	permalink.setAttributeNS(null, "href",
-				 entryYearStr+"-"+entryMonthStr+".html"
-				 +"#"+entryIdStr);
+	if ( entryDoSinglePageStr.equals("") )
+	    permalink.setAttributeNS(null, "href",
+				     entryYearStr+"-"+entryMonthStr+".html"
+				     +"#"+entryIdStr);
+	else
+	    permalink.setAttributeNS(null, "href",
+				     entryYearStr+"-"+entryMonthStr
+				     +"-"+entryDayStr+"-"+entryDoSinglePageStr
+				     +".html"
+				     +"#"+entryIdStr);
 	permalink.setAttributeNS(null, "rel", "bookmark");
 	Element time = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "time");
 	permalink.appendChild(time);
diff --git a/org/madore/damlengine/TodoWeblogIndexSelectElement.java b/org/madore/damlengine/TodoWeblogIndexSelectElement.java
index b82953a..004e330 100644
--- a/org/madore/damlengine/TodoWeblogIndexSelectElement.java
+++ b/org/madore/damlengine/TodoWeblogIndexSelectElement.java
@@ -54,8 +54,12 @@ public final class TodoWeblogIndexSelectElement extends TodoDefaultElement {
 	    String dayStr = matcher.group(3);
 	    String numberStr = String.format("%04d",ent.id);
 	    String targetFile = "";
-	    targetFile = ((ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/"))
-		+ yearStr + "-" + monthStr + ".html";
+	    if ( ent.doSinglePage == null )
+		targetFile = ((ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/"))
+		    + yearStr + "-" + monthStr + ".html";
+	    else
+		targetFile = ((ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/"))
+		    + ent.date + "-" + ent.doSinglePage + ".html";
 	    String targetFragment = "d." + yearStr + "-" + monthStr
 		+ "-" + dayStr + "." + numberStr;
 	    String target = targetFile + "#" + targetFragment;
diff --git a/org/madore/damlengine/TodoWrefAttr.java b/org/madore/damlengine/TodoWrefAttr.java
index d9b8950..9f33406 100644
--- a/org/madore/damlengine/TodoWrefAttr.java
+++ b/org/madore/damlengine/TodoWrefAttr.java
@@ -42,25 +42,34 @@ public class TodoWrefAttr extends TodoAttr {
 	String targetFragment = "d." + wrefYearStr + "-" + wrefMonthStr
 	    + "-" + wrefDayStr + "." + wrefNumberStr + wrefSupplementStr;
 	String target = targetFile + "#" + targetFragment;
-	this.owner.removeAttributeNode(this.attr);
-	this.owner.setAttributeNS(null, "href", target);
 	if ( ! this.owner.hasAttributeNS(null, "class") )
 	    this.owner.setAttributeNS(null, "class", "weblog-internal-link");
-	if ( wrefSupplementStr.equals("")
-	     && ! this.owner.hasAttributeNS(null, "title") ) {
-	    WeblogSummary wsum = WeblogSummary.getSummary();
-	    if ( wsum != null && wsum.entries != null ) {
-		WeblogSummary.EntrySummary esum
-		    = wsum.entries.get(new Integer(wrefNumberStr));
-		if ( esum != null ) {
-		    if ( ! ((wrefYearStr+"-"+wrefMonthStr+"-"+wrefDayStr)
-			    .equals(esum.date)) )
-			System.err.println("warning: date mismatch for reference to entry "+wrefNumberStr);
-		    if ( esum.title != null )
-			this.owner.setAttributeNS(null, "title", esum.title);
+	WeblogSummary wsum = WeblogSummary.getSummary();
+	if ( wsum != null && wsum.entries != null ) {
+	    WeblogSummary.EntrySummary esum
+		= wsum.entries.get(new Integer(wrefNumberStr));
+	    if ( esum != null ) {
+		if ( ! ((wrefYearStr+"-"+wrefMonthStr+"-"+wrefDayStr)
+			.equals(esum.date)) )
+		    throw new IllegalArgumentException("date mismatch for reference to entry "+wrefNumberStr);
+		if ( esum.doSinglePage != null
+		     && ! wrefSupplementStr.equals("")
+		     // Note to self: remember we could be called from d:wxref
+		     // because of link on "older entries": we don't want
+		     // to link to single entry page in this case. :-\
+		     && ! ( ctx.wsc instanceof Context.WeblogSingleSelectionContext ) ) {
+		    targetFile = ((ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/"))
+			+ esum.date + "-" + esum.doSinglePage + ".html";
+		    target = targetFile + "#" + targetFragment;
 		}
+		if ( wrefSupplementStr.equals("")
+		     && ! this.owner.hasAttributeNS(null, "title")
+		     && esum.title != null )
+		    this.owner.setAttributeNS(null, "title", esum.title);
 	    }
 	}
+	this.owner.removeAttributeNode(this.attr);
+	this.owner.setAttributeNS(null, "href", target);
     }
 
 }
diff --git a/org/madore/damlengine/WeblogPopulate.java b/org/madore/damlengine/WeblogPopulate.java
index 9b6694e..6593f9f 100644
--- a/org/madore/damlengine/WeblogPopulate.java
+++ b/org/madore/damlengine/WeblogPopulate.java
@@ -46,13 +46,13 @@ public final class WeblogPopulate {
 	final PreparedStatement checkSt
 	    = conn.prepareStatement("SELECT sha1 FROM entries WHERE id=?");
 	final PreparedStatement insertNSt
-	    = conn.prepareStatement("INSERT INTO entries(id,edate,lang,title,title_xml,content,sha1) VALUES (?,?,?,?,?::xml,?::xml,?)");
+	    = conn.prepareStatement("INSERT INTO entries(id,edate,lang,do_single_page,title,title_xml,content,sha1) VALUES (?,?,?,?,?,?::xml,?::xml,?)");
 	final PreparedStatement insertCSt
-	    = conn.prepareStatement("INSERT INTO entries(id,edate,lang,title,title_xml,content,sha1,cdate) VALUES (?,?,?,?,?::xml,?::xml,?,?::timestamptz)");
+	    = conn.prepareStatement("INSERT INTO entries(id,edate,lang,do_single_page,title,title_xml,content,sha1,cdate) VALUES (?,?,?,?,?,?::xml,?::xml,?,?::timestamptz)");
 	final PreparedStatement updateNSt
-	    = conn.prepareStatement("UPDATE entries SET (edate,mdate,lang,title,title_xml,content,sha1)=(?,DEFAULT,?,?,?::xml,?::xml,?) WHERE id=?");
+	    = conn.prepareStatement("UPDATE entries SET (edate,mdate,lang,do_single_page,title,title_xml,content,sha1)=(?,DEFAULT,?,?,?,?::xml,?::xml,?) WHERE id=?");
 	final PreparedStatement updateCSt
-	    = conn.prepareStatement("UPDATE entries SET (edate,mdate,lang,title,title_xml,content,sha1,cdate)=(?,DEFAULT,?,?,?::xml,?::xml,?,?::timestamptz) WHERE id=?");
+	    = conn.prepareStatement("UPDATE entries SET (edate,mdate,lang,do_single_page,title,title_xml,content,sha1,cdate)=(?,DEFAULT,?,?,?,?::xml,?::xml,?,?::timestamptz) WHERE id=?");
 	final PreparedStatement checkDateSt
 	    = conn.prepareStatement("SELECT to_char(cdate,'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') FROM entries WHERE id=?");
 	final PreparedStatement clearCatSt
@@ -85,6 +85,9 @@ public final class WeblogPopulate {
 		cdate = null;
 	    String catStr = ent.getAttributeNS(null, "cat");
 	    String[] catList = catStr.split("\\s+");
+	    String doSinglePage = ent.getAttributeNS(null, "single-page");
+	    if ( doSinglePage.equals("") )
+		doSinglePage = null;
 	    String lang = LangHelper.getLangRec(ent);
 	    String content = ser.writeToString(ent);
 	    sha1.reset();
@@ -108,15 +111,16 @@ public final class WeblogPopulate {
 		    updateSt = updateCSt;
 		updateSt.setString(1, date);
 		updateSt.setString(2, lang);
-		updateSt.setString(3, titleTxt);
-		updateSt.setString(4, titleXml);
-		updateSt.setString(5, content);
-		updateSt.setString(6, digest);
+		updateSt.setString(3, doSinglePage);
+		updateSt.setString(4, titleTxt);
+		updateSt.setString(5, titleXml);
+		updateSt.setString(6, content);
+		updateSt.setString(7, digest);
 		if ( cdate != null ) {
-		    updateSt.setString(7, cdate);
-		    updateSt.setInt(8, id);
+		    updateSt.setString(8, cdate);
+		    updateSt.setInt(9, id);
 		} else {
-		    updateSt.setInt(7, id);
+		    updateSt.setInt(8, id);
 		}
 		updateSt.executeUpdate();
 	    } else {
@@ -129,12 +133,13 @@ public final class WeblogPopulate {
 		insertSt.setInt(1, id);
 		insertSt.setString(2, date);
 		insertSt.setString(3, lang);
-		insertSt.setString(4, titleTxt);
-		insertSt.setString(5, titleXml);
-		insertSt.setString(6, content);
-		insertSt.setString(7, digest);
+		insertSt.setString(4, doSinglePage);
+		insertSt.setString(5, titleTxt);
+		insertSt.setString(6, titleXml);
+		insertSt.setString(7, content);
+		insertSt.setString(8, digest);
 		if ( cdate != null )
-		    insertSt.setString(8, cdate);
+		    insertSt.setString(9, cdate);
 		insertSt.executeUpdate();
 	    }
 	    if ( ! Pattern.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}(?:\\:\\d{2})?(?:Z|[\\+\\-]\\d{2}\\:\\d{2})$", cdate) ) {
diff --git a/org/madore/damlengine/WeblogRSS.java b/org/madore/damlengine/WeblogRSS.java
index 147c8f5..0f3b296 100644
--- a/org/madore/damlengine/WeblogRSS.java
+++ b/org/madore/damlengine/WeblogRSS.java
@@ -27,7 +27,7 @@ public final class WeblogRSS {
 	final Connection conn = WeblogDatabaseConnection.getConnection();
 
 	final PreparedStatement selSt
-	    = conn.prepareStatement("SELECT id , edate , to_char(cdate,'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') , lang , title , content FROM entries ORDER BY id DESC LIMIT 25");
+	    = conn.prepareStatement("SELECT id , edate , to_char(cdate,'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') , lang , do_single_page , title , content FROM entries ORDER BY id DESC LIMIT 25");
 
 	final ResultSet selRes = selSt.executeQuery();
 
@@ -97,8 +97,9 @@ public final class WeblogRSS {
 	    String date = selRes.getString(2);
 	    String cdate = selRes.getString(3);
 	    String lang = selRes.getString(4);
-	    String title = selRes.getString(5);
-	    String contentXml = selRes.getString(6);
+	    String doSinglePage = selRes.getString(5);
+	    String title = selRes.getString(6);
+	    String contentXml = selRes.getString(7);
 	    Matcher matcher = Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2})$").matcher(date);
 	    if ( ! matcher.matches() )
 		throw new IllegalArgumentException("entry "+id+" has badly formed date");
@@ -108,9 +109,15 @@ public final class WeblogRSS {
 	    String numberStr = String.format("%04d",id);
 	    String aboutUri = weblogBaseURI
 		+ "#d." + date + "." + numberStr;
-	    String linkUri = weblogBaseURI
-		+ yearStr + "-" + monthStr + ".html"
-		+ "#d." + date + "." + numberStr;
+	    String linkUri;
+	    if ( doSinglePage == null )
+		linkUri = weblogBaseURI
+		    + yearStr + "-" + monthStr + ".html"
+		    + "#d." + date + "." + numberStr;
+	    else
+		linkUri = weblogBaseURI
+		    + date + "-" + doSinglePage + ".html"
+		    + "#d." + date + "." + numberStr;
 	    Element li = rssDoc.createElementNS(DamlEngine.RDF_NS, "rdf:li");
 	    itemsSeq.appendChild(li);
 	    itemsSeq.appendChild(rssDoc.createTextNode("\n"));
diff --git a/org/madore/damlengine/WeblogSummary.java b/org/madore/damlengine/WeblogSummary.java
index babfcf5..997f67a 100644
--- a/org/madore/damlengine/WeblogSummary.java
+++ b/org/madore/damlengine/WeblogSummary.java
@@ -13,13 +13,16 @@ public final class WeblogSummary {
 	String date;
 	String lang;
 	String title;  String titleXml;
+	String doSinglePage;
 	public EntrySummary(int id, String date, String lang,
-			    String title, String titleXml) {
+			    String title, String titleXml,
+			    String doSinglePage) {
 	    this.id = id;
 	    this.date = date;
 	    this.lang = lang;
 	    this.title = title;
 	    this.titleXml = titleXml;
+	    this.doSinglePage = doSinglePage;
 	}
     }
 
@@ -38,7 +41,7 @@ public final class WeblogSummary {
 	try {
 	    final Connection conn = WeblogDatabaseConnection.getConnection();
 	    final PreparedStatement selSt
-		= conn.prepareStatement("SELECT id , edate , lang , title , title_xml FROM entries");
+		= conn.prepareStatement("SELECT id , edate , lang , title , title_xml , do_single_page FROM entries");
 	    final ResultSet selRes = selSt.executeQuery();
 	    while ( selRes.next() ) {
 		int id = selRes.getInt(1);
@@ -46,7 +49,8 @@ public final class WeblogSummary {
 		String lang = selRes.getString(3);
 		String title = selRes.getString(4);
 		String titleXml = selRes.getString(5);
-		singleton.entries.put(new Integer(id), new EntrySummary(id, date, lang, title, titleXml));
+		String doSinglePage = selRes.getString(6);
+		singleton.entries.put(new Integer(id), new EntrySummary(id, date, lang, title, titleXml, doSinglePage));
 	    }
 	} catch (SQLException e) {
 	    // Well, we'll have no summary.  Too bad, but better than abort.
diff --git a/org/madore/damlengine/weblog-cat-template.daml b/org/madore/damlengine/weblog-cat-template.daml
index 7219ea3..3074057 100644
--- a/org/madore/damlengine/weblog-cat-template.daml
+++ b/org/madore/damlengine/weblog-cat-template.daml
@@ -53,6 +53,8 @@ href="http://www.madore.org/cgi-bin/comment.pl/lscomments">Recent
 comments — <span xml:lang="fr">Commentaires
 récents</span></a></p>
 
+<div class="cleared-right" d:xempty="xempty" />
+
 <p>Entries with category <q><d:weblog-selection-cat-code /></q>
 / <span xml:lang="fr">Entrées de la
 catégorie <q><d:weblog-selection-cat-code /></q></span>:</p>
diff --git a/org/madore/damlengine/weblog-database.sql b/org/madore/damlengine/weblog-database.sql
index ab4146d..0cfd282 100644
--- a/org/madore/damlengine/weblog-database.sql
+++ b/org/madore/damlengine/weblog-database.sql
@@ -7,8 +7,9 @@ CREATE TABLE entries (
 	lang text ,
 	title text ,
 	title_xml xml ,
-	content xml NOT NULL,
-	sha1 text NOT NULL
+	content xml NOT NULL ,
+	sha1 text NOT NULL ,
+	do_single_page text
 ) ;
 CREATE INDEX entries_edate_key ON entries ( edate ) ;
 CREATE TABLE incat (
diff --git a/org/madore/damlengine/weblog-month-template.daml b/org/madore/damlengine/weblog-month-template.daml
index 06883ec..129d20a 100644
--- a/org/madore/damlengine/weblog-month-template.daml
+++ b/org/madore/damlengine/weblog-month-template.daml
@@ -53,6 +53,8 @@ href="http://www.madore.org/cgi-bin/comment.pl/lscomments">Recent
 comments — <span xml:lang="fr">Commentaires
 récents</span></a></p>
 
+<div class="cleared-right" d:xempty="xempty" />
+
 <p>Entries of month
 <d:weblog-selection-month-year />-<d:weblog-selection-month-month />
 / <span xml:lang="fr">Entrées du mois
diff --git a/org/madore/damlengine/weblog-recent-template.daml b/org/madore/damlengine/weblog-recent-template.daml
index 2938edc..c39f63b 100644
--- a/org/madore/damlengine/weblog-recent-template.daml
+++ b/org/madore/damlengine/weblog-recent-template.daml
@@ -66,6 +66,8 @@ href="http://www.madore.org/cgi-bin/comment.pl/lscomments">Recent
 comments — <span xml:lang="fr">Commentaires
 récents</span></a></p>
 
+<div class="cleared-right" d:xempty="xempty" />
+
 <d:weblog-select />
 
 <p>Only the <d:weblog-selection-recent-count /> most recent entries
diff --git a/org/madore/damlengine/weblog-single-template.daml b/org/madore/damlengine/weblog-single-template.daml
index 673ee32..7d17018 100644
--- a/org/madore/damlengine/weblog-single-template.daml
+++ b/org/madore/damlengine/weblog-single-template.daml
@@ -33,13 +33,13 @@ href="http://www.madore.org/cgi-bin/comment.pl/lscomments">Recent
 comments — <span xml:lang="fr">Commentaires
 récents</span></a></p>
 
+<div class="cleared-right" d:xempty="xempty" />
+
 <p>Entry #<d:weblog-selection-single-number />
 / <span xml:lang="fr">Entrée #<d:weblog-selection-single-number /></span>:</p>
 
 <d:weblog-select />
 
-<hr />
-
 </d:body>
 
 </d:daml>
-- 
cgit v1.2.3