A short story:
Once there was a unicode string, let's call him Srcdir.
Along came a crufy old File::Find, who went through a tree and pasted each
of the leaves in turn onto Srcdir. But this 90's relic didn't decode the
leaves -- despite some of them using unicode! Poor Srcdir, with these
leaves stuck on him, tainted them with his nice unicode-ness. They didn't
look like leaves at all, but instead garbage.
In other words, perl's unicode support sucks mightily, and drives
us all to drink and bad storytelling. But we knew that..
So, srcdir is not normally flagged as unicode, because typically it's pure
ascii. And in that case, things work ok; File::Find finds filenames, which
are not yet decoded to unicode, and appends them to the srcdir, and then
decode_utf8 happily converts the whole thing.
But, if the srcdir does contain utf8 characters, that breaks. Or, if a Yaml
setup file is used, Yaml::Syck's implicitunicode sets the unicode flag of
*all* strings, even those containing only ascii. In either case, srcdir
has the unicode flag set; a non-decoded filename is appended, and
decode_utf8 sees the flag and does *nothing*. The result is that the
filename is not decoded, so looks valid and gets skipped.
File::Find only sticks the directory and filenames together in no_chdir
mode .. but we need that mode for security. In order to retain the
security, and avoid the problem, I made it not pass srcdir to File::Find.
Instead, chdir to the srcdir, and pass ".". Since "." is ascii, the problem
is avoided.
Note that it takes care to chdir back to the starting location. Because
the user may have specified relative paths and so staying in the srcdir
might break. A relative path could even be specifed for an underlay dir, so
it chdirs back after each.
The bug here was that disabling a plugin included thru goodstuff, like
htmlscrubber, caused it to be added to disable_plugins, and those plugins
were never loaded, so could not be re-enabled. Fix by allowing them to be
force loaded when appropriate. (Also that allows disabled plugins to still
record their setup options when dumping a setup file.)
* calendar: Shorten day names, and improve styling of month calendar.
* style.css: Reduced sidebar width back to 20ex from 30; the month calendar
will now fit in the smaller width, and 30 was feeling too large.
The key is using width: auto; overflow: auto; -- this allows the div(s) to the
left of the floating sidebar to be resized to fit next to it, and prevents
any clear: both from pushing the div down below the end of the sidebar.
Many thanks for the Hurd wiki's developers for originally figuring this out.
The edit page recently developed the same problem with its textarea, now
that a sidebar can appear on that page too. In editpage.tmpl I needed to
add a new div around the editcontent textarea, as the above styles cannot
be applied directly to textareas. The textarea's own width is reduced to
98% because at least in chromium this avoids it getting unnecessary
horizonatl scrollbars when a sidebar is displayed next to it.
http://bzed.de/posts/2010/05/new_css_for_bzed.de/
smcv: [10:59:01] is the logical thing you want a <div> whose meaning is "the bits the sidebar is allowed to accompany"?
bzed: [10:59:14] yeah
bzed: [10:59:58] then you could just ensure that this part is as high as the sidebar
smcv: [11:02:44] wrapping a <div> around the sidebar, content and comments seems like the way forward, then
The linktype check was being done on the relativised link target,
but %typedlinks uses the same link targets as %links, so that didn't work.
I think the bug only appeared when tagbase was not set.
This bugfix also let me factor out the common typedlink checking code.
To match calendars, which use local time. Particularly important at
the end of the month.
I checked the history, and there seemed no good rationalle for the
pagespecs to use gmtime.
Problem is that by the time rendering calls render_dependent, %pagesources
has had deleted files removed from it. So match_comment's lookup of
files in there to see if they had the _comment extension failed.
I had to introduce a hash that temporarily holds filenames of deleted pages
to fix this.
Note that unlike comment(), internal() had avoided this pitfall by being
defined to match both internal and non-internal pages.
* openid: Incorporated a fancy openid-selector signin form.
(http://code.google.com/p/openid-selector/)
* openid: Use "openid_identifier" as the form field, as required
by OpenID Authentication v2.0 spec.
test isinternal first, because match_glob with internal => 1 also returns
non-internal pages that match. This order should also be faster.
Remove test to see if pagesources is set. isinternal will not succeed if it
is not.
* comments: Comments pending moderation are now stored in the srcdir
alongside accepted comments, but with a `._comment_pending` extension.
* This allows easier byhand moderation, as the "_pending" need
only be stripped off and the comment be committed to version control.
* The `comment_pending()` pagespec can be used to match such unmoderated
comments, which makes it easy to add a feed of them, or a counter
indicating how many there are.
* Belatedly added a `comment()` pagespec.
Turns out that users with a modified page.tmpl need to modify it on
upgrade, at least to add the FORCEBASEURL (so edit preview works),
so there is no point in trying to retain compatability.
* Removed misc.tmpl. Now to theme ikiwiki, you only need to customise
a single template, page.tmpl.
* misc.tmpl will, however, still be read if a locally modified version
exists. This is to avoid forcing users to update page.tmpl right now.
This is a first pass, it avoids needing to change style.css
except where it refers to tag types.
This goes a bit off the rails at the pageheader with its nested header.
Semantically, there should be an article around the whole page
header, content, and footer. Just as there will be an article around a
whole comment or inlined page header, content, and footer.
But that will mean changing the css that currently refers to pageheader to
refer to the enclosing article instead.
* Ikiwiki can be configured to generate html5 instead of the default xhtml
1.0. The html5 output mode is experimental, not yet fully standards
compliant, and will be subject to rapid change.
Needed to handle the move of the .js files into ikiwiki/, but also this is
a longstanding bug.
Old pagemtime is not remembered in rebuild mode, and changing that would
need a lot of changes. So instead, loop on pagectime, which is remembered.
Change to remembering old pagesources info in rebuild mode. This seems safe
enough.
This is a slow implementation; it runs svn log once per file
still, rather than running svn log once on the whole srcdir.
I did it this way because in my experience, svn log, run on a directory,
does not always list every change to files inside that directory.
I don't know why, and I use svn as little as possible these days.
* Automatically run --gettime the first time ikiwiki is run on
a given srcdir.
* Optimise --gettime for git, so it's appropriatly screamingly
fast. (This could be done for other backends too.)
* However, --gettime for git no longer follows renames.
* Use above to fix up timestamps on docwiki, as well as ensure that
timestamps on basewiki files shipped in the deb are sane.
* Rename --getctime to --gettime. (The old name still works for
backwards compatability.)
* --gettime now also looks up last modification time.
* Add rcs_getmtime to plugin API; currently only implemented
for git.
* pagestats: Class parameter can be used to override default class for
custom styling.
* pagestats: Use style=list to get a list of tags, scaled by use like
in a tag cloud. This is useful to put in a sidebar.
* Rework example blog front page.
The meta title data set by comments needs to be encoded the same way that
meta encodes it. (NB The security implications of the missing encoding
are small.)
Note that meta's encoding of title, description, and guid data, and not
other data, is probably a special case that should be removed. Instead,
these values should be encoded when used. I have avoided doing so here
because that would mean forcing a wiki rebuild on upgrade to have the data
consitently encoded.
For a while, I was avoiding capitalizing ikiwiki at the beginning of a
sentence. I now think that's a bad idea (unless explicitly referring to
the `ikiwiki` command). Still, I don't go all the way and always cap it,
as a proper noun. That would make the logo look bad. ;)
I also tend to avoid capping it as IkiWiki, except when referring to the
perl internals, which do use that capitalization. (Too late to change
that.) However, it's also reasonable to do so in a WikiLink, as a nod to
historical camelcase wikis.
Colons are not allowed at the start of urls, because it can be interpreted
as a protocol, and allowing arbitrary protocols can be unsafe
(CVE-2008-0809). However, this check was too restrictive, not allowing
use of eg, "video.ogv?t=0:03:00/0:04:00" to seek to a given place in a
video, or "somecgi?foo=bar:baz" to pass parameters with colons.
It's still not allowed to have a filename with a colon in it (ie
"foo:bar.png") -- to link to such a file, a fully qualified url must be
used.
Since Firefox version 3, it's done aggressive caching of visited pages, and
does not, by default, check if the cached content is still valid when
reloading or revisiting a page. By default, Firefox seems to not re-contact
the web server at all. Compare with eg, Epiphany and Chromium, which appear
to always check, and get back a 304 when the page is unchanged.
This header makes Firefox do the right thing, at least for html files. It
still over-caches if css, javascript, images, etc, are changed.
The info is stored in the session database, not the user database.
There should be no reason to need it when a user is not logged in.
Also, hide the email field in the preferences page for openid users.
Note that the email and username are not yet actually used for anything.
The email will be useful for gravatar, while the username might be used
for a more pretty display of the openid.
* moderatedcomments: Added moderate_pagespec that can be used
to control which users or comment locations are moderated.
This can be used, just for example, to moderate http://myopenid.com/*
if you're getting a lot of spammers from one particular openid
provider (who should perhaps answer your emails about them),
while not moderating other users.
* moderatedcomments: The moderate_users setting is deprecated. Instead,
set moderate_pagespec to "!admin()" or "user(*)" instead.
This prevented comments containing some utf-8, including euro sign, from
being submitted. Since md5_hex is a C implementation, the string has to be
converted from perl's internal encoding to utf-8 when it is called. Some
utf-8 happened to work before, apparently by accident.
Note that this will change the checksums returned.
unique_comment_location is only used when posting comments, so the checksum
does not need to be stable there.
I only changed page_to_id for completeness; it is passed a comment page
name, and they can currently never contain utf-8.
In teximg, the bug could perhaps be triggered if the tex source contained
utf-8. If that happens, the checksum will change, and some extra work might
be performed on upgrade to rebuild the image.
This was not doable before, but when I added transitive dependency handling
in the big dependency rewrite, it became possible to include a comment
count when inlining.
This also improves the action link when a page has no comments. It will
link direct to the cgi to allow posting the first comment. And if the page
is locked to prevent posting new comments, the link is no longer shown.
Now that openiduser is in IkiWiki core, it's ok to have passwordauth check
for it, and avoid displaying useless password fields when showing
preferences for an openid.
Also improved the styling of the display of the openid in the preferneces
page.
Consider a template like:
[[!template type=note text="""
[[!inline pages="*foo*"]]
"""]]
The text parameter is htmlized before being passed into the template (in
case the template wraps it in a <span> that prevents markdown from
htmlizing it later).
But, when markdown sees "*foo*", it turns that into <em>foo</em>.
Later, when preprocessing the inline directive, that leads to suprising
results.
To fix this, I made template parameters be preprocessed (and filtered)
before being htmlized.
Note that I left in the preprocessing (and filtering) of the template
output at the end. That's still relevant when the template itself contains
preprocessor directives.
Note that there is an associated po4a warning when a page is empty:
Use of uninitialized value $file in substitution (s///) at /usr/share/perl5/Locale/Po4a/Text.pm line 205.
I've filed a bug with po4a about that, but the important thing is fixing
the crash here.