Update (200911-08): I've stopped using this, because it made the archive generating fail in mysterious ways...
As you might have seen I have now these nice (opinions may vary) "more..." links in my blog. This is done with some JavaScript and shell foo and in this entry I will explain how I did it.
The setup also works with text browsers and
people who disable JavaScript. In the latter
case you will get the normal nb behavior
where you see the entire article. When using
a text browser you also see the entire article
but there is also a (non functional) 'more' link.
User side
When writing a blog entry the only thing you need to do is to put the following on a line
- read more -
(technically you need more -'s to make it work, but this will suffice for this example).
Anything you type below that line will become collapsible with a 'more' link. Anything above will be directly visible.
Implementation
First a shell script which reads your entire blog
entry and replaces the - read more- with the html
and JavaScript to make it work.
#!/bin/bash
EPOCH=$(date +%s)
ART_ID="art_$$_$EPOCH"
HREF_ID="href_$$_$EPOCH"
DATA=$(cat)
# escape galore
repl="<script type=\"text\/javascript\">\n\
<!--\n\
function toggle_visibility(id, anchor) {\n\
var e = document.getElementById(id);\n\
var a = document.getElementById(anchor);\n\
if(e.style.display == 'block') {\n\
e.style.display = 'none';\n\
a.innerHTML = \"\« more ...\";\n\
} else {\n\
e.style.display = 'block';\n\
a.innerHTML = \"\« less\";\n\
}\n\
}\n\
\/\/-->\n\
<\/script>\n\
<div class=\"readmore\">\n\
<a class=\"readmore\" style=\"display: none;\" id=\"$HREF_ID\"\n\
href=\"javascript:\/\/\" onclick=\"toggle_visibility(\'$ART_ID\', \'$HREF_ID\');\">\
\» more ...<\/a>\n\
<\/div>\n\
<div id=\"$ART_ID\">\n\
<script type=\"text\/javascript\">\n\
<!--\n\
e = document.getElementById('$ART_ID');\n\
e.style.display = 'none';\n\
e = document.getElementById('$HREF_ID');\n\
e.style.display = 'block';\n\
\/\/-->\n\
<\/script>\n\
"
if echo "$DATA" | egrep -q -- '-{3,}.?read.more.?-{3,}'; then
echo "$DATA" | sed -r "s/-{3,}.?read.more.?-{3,}/$repl/"
echo "</div> <!-- id=$ART_ID -->";
else
echo "$DATA"
fi
As I'm using stdin twice I am capturing it in the variable
$DATA.
The variable $repl is filled and is used
by sed the replace - read more-. It was a real
pain to correctly quote everything (as you might see).
The JavaScript trick to do this collapsing can be easily found on the internet (google: hide/show divs).
interfacing with nanobloggger
You need to edit two templates, entry.htm and permalink.htm,
in the first one you enable the 'read more'-feature and the latter
you need to get rid of the '- read more -' line.
entry.htm
In entry.htm replace
$NB_EntryBody
with
$(echo "$NB_EntryBody" | ${BLOG_DIR}/bin/readmore)
Adjust this to where you have saved the shell script from above.
permalink.htm
On your permalink page this read more stuff is ridiculous, so there we must get rid of it.
Where it says
$NB_EntryBody
replace that with
$(echo "$NB_EntryBody" | sed -r 's/-{3,}.?read.more.?-{3,}//')
to filter out the line.
2 comments
If you are using markdown to write your blog entries you need to make sure the javascript and div stuff isn't put in a paragraph.
This will lead to a block element inside a inline element and will make you page fail to validate.
another update
Note that these read more lines also appear in your rss/atom feeds. So they need to be filtered out.
For /usr/share/nanoblogger/plugins/rss2.sh I changed the following. Where it says
NB_RSS2EntryExcerpt="$NB_EntryBody"change that to:
NB_RSS2EntryExcerpt=$(echo "$NB_EntryBody" | \
sed -r 's/-{3,}.?read.more.?-{3,}//')
So that the line is filtered out. Same applies for
atom.sh

