dwiki: Recent Entries For range/11-20

Subdirectories: NewFeatures.

2006-04-08

New: directories can have an index 'page'

I've decided that sometimes I really want a directory to have an index page, not just a list of the contents. So now I can, with the unimaginatively named 'index' view. It's mostly template based; the normal template uses inject::index to display an __index file. However, the view has several special properties:

  • unlike other directory views, it is not inherited by subdirectories.
  • it is only listed as an available view in the page tools area if there is a file called __index in the directory.
  • if __index is a redirection, the index view will just generate a redirect to the target.

(Thus, the index view could be used to replace the wikiroot configuration directive.)

The index view is valid on directories even without a __index page in the directory. Right now the template just displays a normal directory listing in that case.

Written 19:56:37 by cks.

2006-03-25

New: #pragma search ...

I got tired of the relative links in my blog drafts (written in an entirely different directory than their eventual home) not working. So, introducing #pragma search; this adds additional directories to search for pages when resolving relative links, both WikiWords and explicit [[...]] links. The directories listed in a search pragma must be absolute path names, and are searched only after the hard-coded possibilities have been exhausted (including the alias directory for WikiWords).

You can't have both a #pragma search ... and a #pragma pre in the same page, partly because it doesn't make any sense. (This is the simple way of getting out of handling multiple #pragma directives.)

Written 23:30:58 by cks.

Formatting, 21:01:04 by cks

Ye Olde Formatting Teste

This is, naturally, a test of how all of our formatting actually looks. (It has turned into sort of documenting things, too. You probably want to view the source, using the toolbar at the bottom.)

Lists:

I'm not going to try to explain lists. Once you follow View Source, it should be obvious. The only tricky bit is that a list line that is continued on following lines must be indented; a flush-left line will be taken as returning to the paragraph (or starting one). List demo:

  • This is an unordered list.
  • with another entry continued on another line (see View Source).
    1. A nested numbered list.
      1. ... and going deeper!
      • Still nested, but we've switched styles.
    • And we can abruptly switch styles as we de-nest, as we did here.
    And back to the original list entry.
  • back down to the original unordered list.

And back to the land of happy paragraphs. We've also got the third type of list on hand:

definition lists
... which may come in handy when I get around to writing up detailed documentation on this thing.
this thing being
DWiki. Configuration, TemplateSyntax, operation, etc.

Definition lists don't come out quite as they're written in ASCII, but it's closer than some of the other choices. Definition lists nest with more leading characters, like the other lists.

Nested Lists

The primary way of writing nested lists is to actually indent the nested lists in the wikitext, as you can see in the 'View Source' for this page. Sometimes this is awkward; in that case, you can use more than one of the list-start characters, like this:

  • A list.
    • Another nested list with another line.
      • Really nested.
    1. List types can change.
  • And we're done.

Note that if you continue such a nested list on a new line, the new line's indentation must be deeper than the start characters for the list.

Tables:

left right
up 10 20
down 30 40

Tables are extremely low-rent. Chris figures that this pretty much matches what he wants.

The downside is that more complicated tables may render, how shall we say, a little less than optimally. You're best off sticking to tables that have something in all of the cells and that are always the same shape.

'Horizontal' tables, where the only border lines are horizontal and fainter, are created by starting a table with |_. instead of |:

Code Meaning Look at body?
200 Successful page fetch Yes (if GET)
301 (Permanent) redirect No
304 Not modified No
404 Access denied (don't retry) Only for error text

FIXME: I need to do more work on styling tables well. At the moment they are barely better than just sticking ASCII blocks in. I can steal ideas from other WikiText implementations.

Links:

Link formats:

  • Straight URL as text: http://www.google.com/
  • Explicitly marked wiki links: Chris. For in-wiki links, the name shown is shortened to the last component. These can also be external http:// links, or absolute local URLs if they're written with < and > around them, eg [[</>]].
  • Marked links with specific text: the crazed person behind this. Because I keep using || instead of just |, you can use either to separate the label and the link.
  • Marked links with space-separated words: Chris Siebenmann. The last word is taken as the link destination.
  • CamelCase names as wiki links: People/ChrisSiebenmann. CamelCase words are only links if the target page exists.

The preferred link format for internal wiki links is the explicit wiki link [[....]], because that allows a wider variety of useful names than CamelCase. (eg, I do not want to have to CamelCase the names of all of the machines I want to write about.)

Interpreting wiki links

The DWiki path '/' is the wiki root, in an analogy to Unix and URI roots. An absolute wiki link starts with / and always refers to that absolute DWiki page.

[[...]] links are considered relative by default (and can include '..' and so on as desired), except that if there's no page by the relative name and there is a page if we consider it an absolute link, DWiki does so. (This keeps me from having to write / at the start of all my absolute links in [[...]]'s.)

CamelCase links are considered absolute by default, but if the absolute version isn't found and a relative version is, that gets used. If neither is found, DWiki tries an alias directory if that's configured, and if that fails the CamelCase is not a link.

Thus all of the CamelCase DWiki's in this paragraph actually refer to the root /DWiki. The wiki link DWiki refers to the current directory one, /dwiki/DWiki. (This is unfortunately obscured by DWiki's new habit of rewriting CamelCase links that point to redirects to the redirection target, but trust Chris, this is what's actually happening.)

[Actually these days DWiki retargets all links that point to redirects, which may or may not be the right thing to do but does make it much harder to see this.]

Link abbreviations

Every time you give a [[...]] link both text and a link (with either [[...|...]] or [[... ... ...]]), DWiki remembers the pairing of the text and the link. Afterwards, you can use either as a link abbreviation; it will expand to the full pair.

The (almost) unambiguous form is to use | at the start or the end of the [[...]]: at the end to use the name of the link, at the end to use the URL of the link (whichever is shorter). Eg, Chris Siebenmann.

You can write [[<text>]] without the |. This is always taken to be a name abbreviation, and only if there are spaces in <text> or <text> isn't an absolute URL (http:// or with < and > around it) or a real DWiki page.

Text formatting:

Running text (in paragraphs, lists, tables, and in general all containers) is styled with fonts, links, macros, and magic line breaks.

A ' \\' (space backslash backslash) at the end of a line, and only at the end of a line, produces a <br/>.

Font styles:

Bold, type writer text, and italic. Note that if we don't close one, like say ~~bold here, that it dies at the end of the paragraph.

No stray formatting putting 2/3rds of your text into italic, nosirree. I like my formatting self-contained.

There is one other font style: code style, which produces things like 'char *dp_null;'. Code style is monospace with no further font interpretation, and is done by a ((...)) construct. It exists because ChrisSiebenmann keeps doing it by other, hackier means.

I could have used / for italics, but one major usage of dwiki is going to be documenting our Unix systems. When doing this I will be writing a lot more file paths than italics. Similarly, monospace gets used more often than italics (or underline).

NOTE: the font styles are applied with heuristics. See DWikiText for the full details.

Macro font styles

The ST macro is written {{ST:<style>:text ...}}, and formats the enclosed text in the given HTML font style, which must be one of big, small, strike, sub, sup, or u.

The C macro is used to insert a HTML character entity as either a decimal number, a hexadecimal number starting with x, or a named character entity from the list in CharacterEntities. Note that not all of them are sensible entities, and some of the more exotic of these may not render in the browser of your choice, although all of them are valid HTML 4.01 transitional.

Some examples: И, the Cyrillic capital letter "I"; 水, the Chinese character for water. Certain sorts of cuteness are ruthlessly exterminated, like {{C:funky}}, {{C:10}} or {{C:x1F}}.

Having numeric character entities be valid in your DWiki's chosen character set is up to you. (Of course, the only really sensible character set these days is utf-8.)

HTML <abbr> elements are written {{AB:<abbreviation>[:text ...]}}. Once an abbreviation has been used once its expansion is remembered, so you can write API once and then thereafter use just {{AB:API}} to get API. An abbreviation without an available expansion is considered an invalid macro, so that you notice.

(AB torture test: SWD.)

Unlike most macros, these can be used in comments.

Others:

A line of dashes will produce a horizontal cut, like:


this. You need at least four. These can come pretty much anywhere.

If you don't like really big horizontal lines, there's also the three-stars separator style, like so:

* * *

This is written as '* * *' without line indentation (although you can put more whitespace between the stars if you want).

Indents produce code:

Like so.
This is literal preformatted text and is going to stay that way.
(I suppose you can do ASCII tables if you're so inclined.)

Notice that that was all one <pre> block. Also notice that that HTML markup was quoted, just like this '&' will be.

You need at least one whitespace character on the line. More than one whitespace character produces real in-<pre> whitespace out of the rest, like so:

Left.
 Indented one more space, with & and <pre> thrown in as a bonus.
Back left.

Quoting things

I don't quite know what to call this, but you can quote things just like you would in email: put '> ' at the start of the quote lines.

Like so.
This is a new quoted paragraph.

Quotes nest, too.

You can put anything in a quote that you could put in normal text, and it will all work out right. For example:

  • lists.
  • and everything nests.

Even if you go back one level.

Quotes disappear when you stop putting the quotes in. Despite what the semantic markup people may tell you, feel free to use quotes to produce indentation if it works for you.

Macros

{{...}} is a macro. Macros are used to do special magic expansion. Macros can take parameters, separated with :'s. Available macros currently are:

  • AB: Generate an inline HTML <abbr> element. The first argument is the abbreviation and the following arguments are the expansion. Once the abbreviation has been used once, the expansion is optional.
  • AllPages: List all pages. Arguments are prefixes of page paths and page names to restrict the list to. If you simply want to list all pages under a particular directory, you should use AllPagesUnder instead; it is more efficient (and more aesthetic).
  • AllPagesUnder: List all pages under a particular directory, in alphabetical order. Page names are shown relative to this directory (eg 'fred' instead of 'blog/fred' if blog is the directory). If there is no argument, the directory is the current directory of this page; if there is a single argument, it is the directory.
  • C: Insert a character entity. The character entity may be given as a decimal number or as a HTML 4.01 character entity name. See the ShowCharEnts macro for how to display the list of known character entity names.
  • CanComment: Allow authenticated users to comment on a page. Arguments are users to allow or deny access to, as with the Restricted macro. A DWiki without authentication disallows comments, as no one is authenticated.
  • CutShort: Cut off rendering a page right at that point in some contexts. Optional arguments restrict this effect to the specified view(s); it's generally not useful to do this, but if you want to some values are blog, blogdir, or atom. Rendering as a full page can never be cut off. An important note: CutShort is not really a macro. You must put it at the start of a non-indented, non-nested line; it doesn't work anywhere else in text.
  • DocAll: Enumerate all of the first argument (must be 'macros', 'processnotes', 'renderers', or 'textmacros') with their documentation, if any, as a real HTML list. (In other words, you're reading its output.)
  • EnumerateAll: Enumerate all of the first argument, which must be 'macros', 'processnotes' 'renderers', or 'textmacros' as a comma-separated list. The short form version of DocAll.
  • IMG: Generate an inline image. Usage is {{IMG:<loc> width height alt text ...}}, where the height should normally be 'auto', which set the image so that it will automatically scale down for the browser width in modern CSS environments. If the location is not absolute (http:, https:, or starts with a /) it is taken as a location relative to the DWiki staticurl directory. The location cannot include spaces; % encode them if necessary. After the first time you use an image, specifying the width, height, and alt text is optional; if not specified, they default to the last values. If the alt text contains ' ||| ', it is split there to be alt text (before) and title text (afterwards). The title text is what browsers show when you hover over the image.
  • ListDir: List what's in the current directory. An argument restricts it to either files ('files') or subdirectories ('directory').
  • ListRefs: List pages with references to one of the arguments, or where one of the arguments is a word in the page name. This is an expensive operation in a DWiki of any decent size, since it must search through all pages.
  • MatchingPagesUnder: List all pages under a particular directory if their page name contains a word in the provided word list. Usage is {{MatchingPagesUnder:directory:match ....:option ...:exclude ...}}; the third and fourth arguments are optional and may be blank or omitted. Page names are shown relative to the directory (eg 'fred' instead of 'blog/fred' if blog is the directory). By default, pages are shown in reverse chronological order. The optional third argument sets various options, and may include 'c[hron]' for the default reverse chronological order, '+c[hron]' for forward chronological order, 'a[lpha]' for alpbahetical order based on the page name, 't[able]' for a table display similar to what TitleIndex shows, and 'u[tilstoo]' to include utility pages in the results. Without the 't' option, this may be used with PTitles or Striped, although use with PTitles doesn't change the alphabetical sort to use the titles; it is still based on page names.
  • PTitles: Make another macro generate lists of pages using the titles of the pages (if possible), instead of the names of the pages. Invoked as {{PTitles:<macro>[:arg:arg...]}}.
  • RecentChanges: List recently changed pages. First argument is how many to cut the list at, default 50; 0 means no limit, showing everything. Additional arguments are which directories to include or (with a dash at the start) to exclude from the list; you can use '.' to mean the current directory. To preserve the default limit, use a value for the first argument that is not a number. If we're Striped, list pages under their name not their full path.
  • RecentCommentedPages: List pages with recent comments. Arguments are the same as for RecentChanges.
  • RecentComments: List recent comments. Arguments are the same as for RecentChanges. Use with Striped is somewhat dubious.
  • Restricted: Restrict a page to authenticated users. Arguments are which users or groups to allow access to or, with a dash at the front, to deny access to. If both allow and deny arguments are given, the viewing user must pass both tests. Restricted has no effect if the DWiki has no authentication configured.
  • ST: Style text with a particular HTML font style. The first argument is the HTML font style; the remainder are the text to be in that style. Valid styles are big, del, ins, small, strike, sub, sup, and u.
  • ShowCfgVar: Insert the value of a DWiki configuration variable. The argument is which variable to insert. Only a few variables may be displayed, currently wikiname, wikititle, server-name, pagedir, and charset.
  • ShowCharEnts: Show all the known character entities accepted by the C macro as a real HTML list. Takes no arguments.
  • Striped: Make another macro generate lists of pages as a comma-separated line, instead of the real list it would normally use. Invoked as {{Striped:<macro>[:arg:arg...]}}.
  • TitleIndex: Insert a table of dates and entry titles (or relative paths for entries without titles), linking to entries and to the day pages. The table is in reverse chronological order. The single argument is the page hierarchy to do this for; if it is not specified, it is done for the current directory. The actual rendering is done by the blog::titleindex renderer.

This list is generated by the same code that finds macros when turning DWikiText into HTML, so it's guaranteed to be complete. The documentation is hopefully complete, but ChrisSiebenmann may have forgotten to update (or provide) it when he changed the code.

Macros that generate lists of pages generate them as links to the pages in question, which is what you want.

Escaping things:

You can put a ! in front of http://foobar, [[..]], or {{..}} to escape their special meaning. Technically this just escapes the meaning of the special leadin, leaving everything else to get styled stylishly.

If you write [[<text>|]], ie you supply no link name/URL, the text is produced un-DWikiText-ified. (This is different from the case where there is a link, in which the text will be DWikiTexted for fonts (but not links or macros).) This is the only genera way to escape font styling (as ((...)) is not exactly general).

Testing: Google. Yep, that text is styled.

Pragmas

Pragmas have to be the very first line in the page. There are two:

  • #pragma pre (or #pragma plaintext) forces the rest of the page to be treated as plaintext, not wikitext.
  • #pragma search DIR1 [...] adds any listed directories to where DWiki searches for relative links, after all of the hard-coded searches.

The search pragma is handy when drafting pages somewhere other than their final directory.

And that's all folks

At least until ChrisSiebenmann starts adding more.

Disclaimer: not entirely guaranteed to be complete and comprehensive. See wikirend.py in the source code.

2006-03-22

New: optional disk-based caching

Having run out of other ways to really improve performance, I added a disk-based caching infrastructure to DWiki and then put in two caches.

The real cache is the renderer cache, which stores the results of selected renderers (currently just the wikitext renderers). Via some glue it's also used to store the results of the filesystem walk that's the expensive bit of blog::prevnext.

The Brute Force Cache is for dealing with Slashdotting style situations; it just caches complete requests for N seconds when the system seems to be under load. I also hijacked it as a convenient place to add extra caching for Atom feeds and to force this caching on software that doesn't do conditional GET.

(For more details, see Caching.)

This required a new storage pool class. Like the comment store, it uses a customized and restricted interface to write things (and a new interface to read them). The cache storage pool stores objects, not data blobs, using the cPickle module to make the swap back and forth. (This may be a mistake, but it's fast and easy.)

Since removing files in DWiki makes me nervous, I didn't bother to implement any sort of cache cleaning; you get to do that by hand. The cache has TTLs, and the renderer cache has validation layered on top of the cache object store, but when they detect something invalid they just ignore it. (On the other hand, the cache storage layer does use temporary files and rename(), so in a sense it's already removing files.)

In theory the cache interface is generic, so later I can hook up a memcached setup or something without having to change higher-level code.

Written 02:52:40 by cks.

2006-02-27

New: Text formatting via macros

I (ChrisSiebenmann) found myself with a genuine need for text set in HTML <strike>. Rather than try to invent a formatting setup for this that did not make me cringe, I just punted to the easy solution: macros that do text formatting.

So, DWiki now has grown the new macros:

  • ST for the font styles DWiki didn't already have.
  • C for character entities, and ShowCharEnts to show the named entities we support.
  • because I was there anyways, AB for <abbr>, so I could have those cute inline abbreviation expansion things. Tragically <abbr> is not supported by IE 6 and less, so AB may quietly change to generating <acronym> someday.
  • and finally, IMG to generate <img>. Width, height, and alt text is mandatory, and there is a hacky way to also roll title text in too. (Title text is optional.)

Through special black magic, ST, C, and AB can be used in comments (the omission of IMG is deliberate). In theory this lets a commenter cause character set explosions, but in practice a bad commenter can just write UTF-8 directly (UTF-8 is the common and only sane character set choice, so).

Implementing these as macros means that they have some limitations. You can't nest C, AB, or a differently styled ST inside an ST, and currently none of them can be done inside link text ([[....]]).

These macros are a bit of a hack. It's relatively easy to implement bits of HTML this way, but I'm not sure if it's good design overall.

Written 03:48:06 by cks.

2006-02-25

CharacterEntities, 02:17:06 by cks

Character entity names recognized by DWiki

This is the automatically generated big list of character entities recognized by (this) DWiki in the C macro. For the meanings and more precise specifications of these, see the Character entity references in HTML 4 from the HTML 4.01 specification.

Note that not everything in this list may show as a character in your browser, or in other people's browsers. Also, this list is pretty much the full HTML 4.01 list. Older versions of HTML don't define all of these entities; the Wikipedia page is the best reference for what entities are defined in what version of HTML. (Since DWiki doesn't know what HTML version you're labelling its output as, it can't restrict the entities C will accept.)

The character entity list, with names and how they show:

  • Aacute: Á
  • aacute: á
  • Acirc: Â
  • acirc: â
  • acute: ´
  • AElig: Æ
  • aelig: æ
  • Agrave: À
  • agrave: à
  • alefsym: ℵ
  • Alpha: Α
  • alpha: α
  • amp: &
  • and: ∧
  • ang: ∠
  • Aring: Å
  • aring: å
  • asymp: ≈
  • Atilde: Ã
  • atilde: ã
  • Auml: Ä
  • auml: ä
  • bdquo: „
  • Beta: Β
  • beta: β
  • brvbar: ¦
  • bull: •
  • cap: ∩
  • Ccedil: Ç
  • ccedil: ç
  • cedil: ¸
  • cent: ¢
  • Chi: Χ
  • chi: χ
  • circ: ˆ
  • clubs: ♣
  • cong: ≅
  • copy: ©
  • crarr: ↵
  • cup: ∪
  • curren: ¤
  • Dagger: ‡
  • dagger: †
  • dArr: ⇓
  • darr: ↓
  • deg: °
  • Delta: Δ
  • delta: δ
  • diams: ♦
  • divide: ÷
  • Eacute: É
  • eacute: é
  • Ecirc: Ê
  • ecirc: ê
  • Egrave: È
  • egrave: è
  • empty: ∅
  • emsp:  
  • ensp:  
  • Epsilon: Ε
  • epsilon: ε
  • equiv: ≡
  • Eta: Η
  • eta: η
  • ETH: Ð
  • eth: ð
  • Euml: Ë
  • euml: ë
  • euro: €
  • exist: ∃
  • fnof: ƒ
  • forall: ∀
  • frac12: ½
  • frac14: ¼
  • frac34: ¾
  • frasl: ⁄
  • Gamma: Γ
  • gamma: γ
  • ge: ≥
  • gt: >
  • hArr: ⇔
  • harr: ↔
  • hearts: ♥
  • hellip: …
  • Iacute: Í
  • iacute: í
  • Icirc: Î
  • icirc: î
  • iexcl: ¡
  • Igrave: Ì
  • igrave: ì
  • image: ℑ
  • infin: ∞
  • int: ∫
  • Iota: Ι
  • iota: ι
  • iquest: ¿
  • isin: ∈
  • Iuml: Ï
  • iuml: ï
  • Kappa: Κ
  • kappa: κ
  • Lambda: Λ
  • lambda: λ
  • lang: ⟨
  • laquo: «
  • lArr: ⇐
  • larr: ←
  • lceil: ⌈
  • ldquo: “
  • le: ≤
  • lfloor: ⌊
  • lowast: ∗
  • loz: ◊
  • lrm: ‎
  • lsaquo: ‹
  • lsquo: ‘
  • lt: <
  • macr: ¯
  • mdash: —
  • micro: µ
  • middot: ·
  • minus: −
  • Mu: Μ
  • mu: μ
  • nabla: ∇
  • nbsp:  
  • ndash: –
  • ne: ≠
  • ni: ∋
  • not: ¬
  • notin: ∉
  • nsub: ⊄
  • Ntilde: Ñ
  • ntilde: ñ
  • Nu: Ν
  • nu: ν
  • Oacute: Ó
  • oacute: ó
  • Ocirc: Ô
  • ocirc: ô
  • OElig: Œ
  • oelig: œ
  • Ograve: Ò
  • ograve: ò
  • oline: ‾
  • Omega: Ω
  • omega: ω
  • Omicron: Ο
  • omicron: ο
  • oplus: ⊕
  • or: ∨
  • ordf: ª
  • ordm: º
  • Oslash: Ø
  • oslash: ø
  • Otilde: Õ
  • otilde: õ
  • otimes: ⊗
  • Ouml: Ö
  • ouml: ö
  • para: ¶
  • part: ∂
  • permil: ‰
  • perp: ⊥
  • Phi: Φ
  • phi: φ
  • Pi: Π
  • pi: π
  • piv: ϖ
  • plusmn: ±
  • pound: £
  • Prime: ″
  • prime: ′
  • prod: ∏
  • prop: ∝
  • Psi: Ψ
  • psi: ψ
  • quot: "
  • radic: √
  • rang: ⟩
  • raquo: »
  • rArr: ⇒
  • rarr: →
  • rceil: ⌉
  • rdquo: ”
  • real: ℜ
  • reg: ®
  • rfloor: ⌋
  • Rho: Ρ
  • rho: ρ
  • rlm: ‏
  • rsaquo: ›
  • rsquo: ’
  • sbquo: ‚
  • Scaron: Š
  • scaron: š
  • sdot: ⋅
  • sect: §
  • shy: ­
  • Sigma: Σ
  • sigma: σ
  • sigmaf: ς
  • sim: ∼
  • spades: ♠
  • sub: ⊂
  • sube: ⊆
  • sum: ∑
  • sup: ⊃
  • sup1: ¹
  • sup2: ²
  • sup3: ³
  • supe: ⊇
  • szlig: ß
  • Tau: Τ
  • tau: τ
  • there4: ∴
  • Theta: Θ
  • theta: θ
  • thetasym: ϑ
  • thinsp:  
  • THORN: Þ
  • thorn: þ
  • tilde: ˜
  • times: ×
  • trade: ™
  • Uacute: Ú
  • uacute: ú
  • uArr: ⇑
  • uarr: ↑
  • Ucirc: Û
  • ucirc: û
  • Ugrave: Ù
  • ugrave: ù
  • uml: ¨
  • upsih: ϒ
  • Upsilon: Υ
  • upsilon: υ
  • Uuml: Ü
  • uuml: ü
  • weierp: ℘
  • Xi: Ξ
  • xi: ξ
  • Yacute: Ý
  • yacute: ý
  • yen: ¥
  • Yuml: Ÿ
  • yuml: ÿ
  • Zeta: Ζ
  • zeta: ζ
  • zwj: ‍
  • zwnj: ‌

Some tedious but possibly important detail: DWiki takes its list of known character entities from the Python htmlentitydefs module.

2006-02-05

New: Previous and Next links in pages in blog views

The more I have used DWiki for a blog, the more I've realized that I want individual entries to be able to have Previous (entry) and Next (entry) links. At first I resisted because this would require an expensive filesystem walk on even individual page views, but I have now given in and made the blog::prevnext renderer, which will do this if I want.

blog::prevnext generates links directly to the pages, not to /range/N-N/ virtual directories, because I think that works better. (It would be less code the other way, but better links are worth the code.)

Written 02:23:02 by cks.

2005-12-18

New: DWiki can generate Google Sitemaps

I added the ability for DWiki to generate Google Sitemap format XML files, using the view 'sitemap'. The information included is very basic currently: just the URL for each file page, all of them set to priority 0.8 (in the hopes that Google will decide that all of the directories are priority 0.5 and prefer returning file page results).

Google does not say what Content-Type you should return sitemaps in, so I have opted for 'application/xml'.

In the future, something as elaborate as Atom rendering may be done. For now, everything is hardcoded in the sitemap::minurlset renderer.

Updated: now directories are shown too, at priority 0.6. This feature is clearly going to be in flux for a while.

Written 03:37:25 by cks.

2005-09-27

TemplateSyntax, 16:59:21 by cks

What Templates Can Contain

Templates are literal text except for four magic template expansions (call them substitutions or macros if you want): ${...}, #{...}, @{...}, and %{...}.

Generally, it is a fatal error for any of the expansions not to work: undefined variables, missing templates, no renderer by the name you listed in the template, etc.

${...} inserts the value of the named global variable. There are three modifiers to variable expansion:

  • ${|var1|var2|...} is alternatives: it inserts the value of the first of var1, var2, etc that are defined.
  • ${?...} is error-free expansion: it makes it not an error for the rest of the expansion to use undefined variables; instead an empty result is inserted. ${?|...|..} works.
  • ${!...} is cancelling expansion: if the variable or variable sequence isn't defined, the whole template produces nothing.

A ? or ! modifier must come before a | modifier.

Variable expansion always produces valid HTML-quoted results.

@{...} invokes the named renderer and inserts its output. That's it; renderers take no arguments (or guff).

%{...} invokes the named renderer and inserts its output, except that if the renderer produces no output the entire template will produce no output. Thus a template consisting of

Last modified: %{lastmodified} <br/>

is entirely empty if the lastmodified renderer produces nothing, instead of being 'Last modified:' and a line break (which would look ugly).

#{...} is template inclusion: the named template is recursively expanded. Template names are just file names for files under the template root directory (set in DWiki's configuration file). There are three variations:

  • #{|t1|t2|...} is alternative expansion: it inserts the first of t1, t2, etc that expanded to something non-blank.
  • #{?t1|t2|...} is conditional expansion: it only expands the additional templates if t1 expanded to something.
  • #{<t1[|t2|...]} and #{!t1[|t2|...]} are first found expansion, and requires a longer explanation.

First Found Expansion

First found expansion is a way of testing a number of possibly existing templates and using the first one that actually exists. With the #{!...} form it is a fatal error for no template to be found; with the #{<...} form it is not, and the whole expansion is just empty.

Each of the t1, t2, etc alternatives are paths, augmented with expansion operators. There are two:

  • $(<varname>) expands a global variable, like ${...} at the template level. (Unlike ${...}, the variable expansion is not HTML-quoted.)
  • ...<rest> first tries the full path <rest>, and then tries backing up to each of <rest>'s parent directories until they run out. (That's a literal three dots at the start.)

An example may help. With a $(pagename) of dwiki/TemplateSyntax and a $(view-format) of normal, the template inclusion

#{<Overrides/...$(pagename)/magic.tmpl|default/$(view-format).tmpl}

would first try Overrides/dwiki/TemplateSyntax/magic.tmpl, then Overrides/dwiki/magic.tmpl, then Overrides/magic.tmpl, and finally default/normal.tmpl.

An example:

This DWiki uses %{..} and #{|t1|t2} expansion to produce a nice message about a directory being entirely empty of pages if it is, instead of 'The following pages are available in this directory:' followed by nothing at all. (You can see this at Tests/SubTestDir.)

A simplified version of the template for directories is:

#{structure/header.tmpl}
<h1> Directory ${pagename} </h1>
#{|dir/dirconts.tmpl|dir/dirempty.tmpl}
#{structure/footer.tmpl}

The dir/dirconts.tmpl template is:

<p>The following pages are available in this directory: %{listdir}</p>

while the the dir/dirempty.tmpl template is:

<p> This directory is empty. </p>

The %{listdir} in dirconts.tmpl makes the entire template empty if the listdir renderer returns nothing (ie, the directory is empty). Then the #{|..|..} sees that the first template is empty and goes on to use diremtpy.tmpl. If there are files in the directory, the dirconts.tmpl template has content and dirempty.tmpl does not get used.

Available renders

For convenience (mostly ChrisSiebenmann's), here is the canonical list of all available renderers. This is generated by the code itself, so is is guaranteed to be 100% accurate (at least for names; your mileage may vary for documentation):

  • anchor::comment: Generate an anchor start for the current comment. You must close the anchor by hand.
  • anchor::self: Generates an anchor start where the name is the full path to the current page. You must close the anchor by hand.
  • anchor::short: Generates an anchor start where the name is the name of the current page. You must close the anchor by hand.
  • atom::autodisc: Generate a suitable Atom feed autodiscovery <link> string, suitable for inclusion in the <head> section. Generates nothing if there is no Atom recent changes feed.
  • atom::comment: Display the current comment in a way suitable for inclusion in an Atom feed.
  • atom::commentfeed: Generate a link to the Atom comments feed for the current page, if comments are turned on.
  • atom::commentid: Generate a hopefully unique ID for the current comment.
  • atom::comments: Generate an Atom feed of recent comments on or below the current page. Each comment is rendered through syndication/atomcomment.tmpl. Supports VirtualDirectory restrictions, which limit which pages the feed will include comments for.
  • atom::commentstamp: Generate an Atom feed format timestamp for the current comment.
  • atom::commenturl: Generate the URL for the current comment.
  • atom::dirfeed: Generate a link to the Atom feed for the current page if the current page is a directory or the wiki root.
  • atom::feeds: Generate a comma-separated list of all Atom feed links, that are applicable for the current page.
  • atom::feedtitle: Generate an Atom feed title for the current page.
  • atom::feedurl: Generate the URL of this page for the current feed.
  • atom::modstamp: Generate an Atom timestamp for the current page based on its change time.
  • atom::now: Generate an Atom timestamp for right now.
  • atom::pages: Generate an Atom feed of the current directory and all its descendants (showing only the most recent so many entries, newest first). Each page is rendered through syndication/atomentry.tmpl, which should result in a valid Atom feed entry. Supports VirtualDirectory restrictions.
  • atom::pagetag: Generate an Atom entry ID. If the atomfeed-tag configuration option is not defined, this is the same as atom::pageurl. If atomfeed-tag is defined, the entry ID is <tag value>:/<page path>. If atomfeed-tag-time is defined, only pages from after this time are given tag-based IDs; for pages before then, this is the same as atom::pageurl.
  • atom::pageterse: Generate wikitext:terse run through a HTML entity quoter, thus suitable for use in Atom feeds.
  • atom::pageterse:notitle: Generate wikitext:terse:notitle run through a HTML entity quoter, thus suitable for use in Atom feeds.
  • atom::pageurl: Generate the URL of this page in its normal view.
  • atom::recentcomment: Generate an Atom format timestamp for the most recent comment that will be displayed in a comment syndication feed.
  • atom::recentpage: Generate an Atom format timestamp for an Atom page feed for the current directory (and all its descendants).
  • atom::timestamp: Generate an Atom timestamp for the current page.
  • auth::loginbox: Generate the form for a login or logout box. Generates nothing if DWiki authentication is disabled. As a side effect, kills page modification time if it generates anything.
  • blog::blog: Generate a Blog rendering of the current directory: all descendant real pages, from most recent to oldest, possibly truncated at a day boundary if there's 'too many', and sets up information for blog navigation renderers. Each displayed page is rendered with the blog/blogentry.tmpl template. Supports VirtualDirectory restrictions.
  • blog::blogdir: Generate a BlogDir rendering of the current directory: display all real pages in the current directory from most recent to oldest, rendering each with the template blog/blogdirpage.tmpl. Supports VirtualDirectory restrictions.
  • blog::date: Generates a YYYY-MM-DD timestamp of the current page.
  • blog::datecrumbs: Create date breadcrumbs for the blog directory if the current page is in a blog directory but is not being displayed inside a virtual directory. The 'blog directory' is the directory that made the blog view the default view.
  • blog::datemarker: Inside a blog::blog or blog::blogdir rendering, generate a YYYY-MM-DD date stamp for the current page if this has changed from the last page; otherwise, generates nothing.
  • blog::namedate: Generate a Month DD, YYYY timestamp of the current page.
  • blog::next:title: Create a link to the next page (if one exists) for the current page if the current page is in a blog directory but is not being displayed inside a virtual directory; the title of the link is the page's title if available. The 'blog directory' is the directory that made the blog view the default view.
  • blog::owner: Display the owner of the current page.
  • blog::prev:title: Create a link to the previous page (if one exists) for the current page if the current page is in a blog directory but is not being displayed inside a virtual directory; the title of the link is the page's title if available. The 'blog directory' is the directory that made the blog view the default view.
  • blog::prevnext: Create Previous and Next links for the current page if the current page is in a blog directory but is not being displayed inside a virtual directory. The 'blog directory' is the directory that made the blog view the default view.
  • blog::seemonthyear: With blog::blog, generate a 'see more' set of links for the month and the year of the next entry if the display of pages has been truncated.
  • blog::seemore: With blog::blog, generates a 'see more' link to the date of the next entry if the display of pages has been truncated; the text of the link is the target date. This renderer is somewhat misnamed.
  • blog::time: Generate a YYYY-MM-DD HH:MM:SS timestamp of the current page.
  • blog::timeofday: Generates a HH:MM:SS timestamp of the current page.
  • blog::titles: Like blog::blog, except that instead of rendering entries through a template, it just displays a table of dates and entry titles (or relative paths for entries without titles), linking to entries and to the day pages. Respects VirtualDirectory restrictions. Unlike blog::blog, it always displays information for all applicable entries.
  • breadcrumbs: Display a 'breadcrumbs' hierarchy of links from the DWiki root to the current page.
  • comment::atomlink: Just like comment::countlink, except that the URL is absolute and the HTML is escaped so that it can be used in an Atom syndication feed.
  • comment::author: Display the author information for a comment, drawing on the given name, website URL, DWiki login, and comment IP address as necessary and available. Only works inside comment::showall. This potentially generates HTML, not just plain text.
  • comment::comment: Display a particular comment. Only works inside comment::showall.
  • comment::count: Display a count of comments for the current page.
  • comment::countlink: Display the count of comments as a link to show them for the current page.
  • comment::date: Display the date of a comment. Only works inside comment::showall.
  • comment::form: Create the form for writing a new comment in, if the page is commentable by the current user.
  • comment::pre: In a comment-writing context, generate a <pre> block of the comment being written.
  • comment::preview: In a comment-writing context, show a preview of the comment being written.
  • comment::showall: Display all of the comments for the current page (if any), using the template comment/comment.tmpl for each in succession.
  • comment::user: Display the user who wrote a comment if it isn't the default DWiki user. Only works inside comment::showall.
  • comment::write: Generate a link to start writing comments on the current page, if the current user can comment on the page.
  • cond::anonymous: Suceeds (by generating a space) if this is an anonymous request, one with no logged in real user. Fails otherwise.
  • cond::blogclipped: Succeeds (by generating a space) if we are in a blog view that is clipped. Fails otherwise.
  • cond::blogyearmonth: Suceeds (by generating a space) if we are a directory, in a blog view, and we are in a month or year VirtualDirectory. Fails otherwise.
  • cond::invirtual: Succeed (by generating a space) if we are in a VirtualDirectory (either directly or during rendering of a subpage). Fails otherwise.
  • cond::notblogroot: Succeds (by generating a space) if we are a directory that is in a default blog view but is not the directory that made it the default view. Fails otherwise.
  • cond::pageinblog: Succeeds (by rendering a space) if the current page is in a blog directory but is not being displayed inside a virtual directory (ie the page itself is being displayed). This also excludes 'utility' pages.
  • cond::realuser: Suceeds (by generating a space) if this is a request made by a logged-in real user. Fails otherwise. This is the opposite of cond::anonymous.
  • dir::altviews: Generate a list of links to acceptable alternate ways to view the page if it is a directory.
  • error::body: Generates the body for an error page from a template in errors/, if the template exists; otherwise uses a default. Only usable during generation of an error page.
  • error::title: Generate the title for an error from a template in errors/, if the template exists; otherwise uses a default. Only usable during generation of an error page.
  • hist::dirty: If the current page has been RCS-locked, display whether or not it has been modified from the version in RCS.
  • hist::lockedby: If the current page is under RCS and is locked, display who has locked it.
  • hist::revtable: If the current page is under RCS, display a version history table.
  • inject::blogreadme: Like inject::readme, except it looks for __readme only in the 'blog directory', the directory that made the blog view the default view. If there is no such directory between the current directory and the DWiki root directory, this does nothing.
  • inject::index: Insert the wikitext file __index in HTML form, if such a file exists in the current directory.
  • inject::readme: Insert the wikitext file __readme, in HTML form, if such a file exists in the current directory.
  • inject::upreadme: Like inject::readme, except it searches for __readme all the way back to the DWiki root directory, not just in the current directory.
  • lastchangetime: Display the page's last change time, if it has one. The change time is taken from the inode ctime.
  • lastmodified: Display the page's last modification time, if it has one. (This is not the same as the last-modified time that the HTTP response will have, which is taken from all of the pieces that contribute to displaying the page, including all templates.)
  • linkhistory: Generate a link to this page's history called 'View History', if it has any.
  • linknormal: Generate a link to this page's normal view called 'View Normal' if it is a file and we are not displaying it in normal view.
  • linkrelname: Inside blog::blog, generate a link to this page titled with the page's path relative to the blog::blog page. Outside that context, the same as linktoself.
  • linkshort: A link to this page, titled with the page's name.
  • linkshortnormal: A link to this page in the normal view, titled with the page's name.
  • linksource: Generate a link to this page's source called 'View Source', if it has any and you can see it.
  • linktocomments: Create a link to this page that will show comments (if any). Otherwise the same as linktonormal.
  • linktonormal: A link to this page in the normal view, titled with the full page path.
  • linktoself: A link to this page, titled with the full page path.
  • listdir: List the contents of the current directory, with links to each page and subdirectory. Supports VirtualDirectory restrictions, but always shows subdirectories.
  • listofdirs: Display a list of the subdirectories in the current directory.
  • pagetools: Generate a comma-separated list of all 'page tools' links, such as 'View Source' and alternate directory views, that are applicable to the current page.
  • post::oldpage: Generate a link to the origin page for a POST request in a POST form context.
  • range::bar: Display a simple range navigation bar inside a VirtualDirectory.
  • range::blogrange: With blog::blog, generates a day navigation bar if the display of pages has been truncated.
  • range::calbar: With blog::blog, generates a calendar-based navigation bar.
  • range::moreclip: With blog::blog, generate a 'or back N more' link if the display of pages has been truncated outside of a VirtualDirectory context.
  • readmore: Generate a 'Read more' link to this page.
  • rooturl: Generate the URL to the root of this DWiki.
  • rss2::pages: Generate a RSS 2.0 feed of the current directory and all its descendants (showing only the most recent so many entries, newest first). Each page is rendered through syndication/rss2entry.tmpl, which should result in a valid RSS 2.0 feed entry. Supports VirtualDirectory restrictions.
  • rss2::recentpage: Generate an RSS 2.0 format timestamp for an RSS 2.0 page feed for the current directory (and all its descendants).
  • rss2::timestamp: Generate a RSS 2.0 timestamp for the current page.
  • search::display: Display the results of a search.
  • search::enter: Create the search form, if searching is enabled.
  • seterror:permissions: If we are rendering the top level page of a request (ie, not rendering a subpage for blog, blogdir, atom feed, etc context), mark this page as having a permission error. This causes the page to be reported as a HTTP 403 error.
  • sitemap::minurlset: Generate a Google Sitemap set of <url> entities for the directory hierarchy starting at the current directory. Supports VirtualDirectory restrictions.
  • wikitext: Convert wikitext into HTML.
  • wikitext:cache: Convert wikitext into HTML but do not display the result; instead it is just cached for later (re)use. This has three effects. First, it makes variables like ${:wikitext:title} available (as do all other wikitext renderers). Second, it's somewhat more efficient if you intend to use a sequence of wikitext renderers, such as a title one followed by a text one. Third, it can be used as a conditional renderer to check permissions; this renderer succeeds (by generating a space) if permissions allow the wikitext to be displayed, and fails (generating nothing) if they don't.
  • wikitext:firstpara: Convert wikitext into HTML, showing only the first paragraph (and the title) if this is possible. This renderer fails if there is no findable first paragraph. It honors the {{CutShort}} macro.
  • wikitext:notitle: Convert wikitext into HTML but without the title.
  • wikitext:short: Convert wikitext into HTML, honoring the {{CutShort}} macro.
  • wikitext:terse: Convert wikitext into terse 'absolute' HTML, with all links fully qualified and no macros having any effect except CutShort, CanComment, IMG, and Restricted.
  • wikitext:terse:notitle: Convert wikitext into terse 'absolute' HTML with all links fully qualified et al (as with wikitext:terse) but omit the title of the page, as with wikitext:notitle.
  • wikitext:title: Generate and return the title of a wikitext page.
  • wikitext:title:html: Generate and return the title of a wikitext page complete with its surrounding '<hN>' and '</hN>' tags.
  • wikitext:title:nohtml: Generate and return the title of a wikitext page without HTML markup.
  • wikitext:title:nolinks: Generate and return the title of a wikitext page without links.

For quite a lot of these, the best real documentation is to see how they are used in the default DWiki template set. (Which is unfortunately a bit of a dark twisted maze at the moment.)

Renderers normally produce things about or from the current page, although some of them (for use in peculiar context) operate on other things. Unless otherwise specified, all renderers are silent if they can't produce something appropriate, which is handy for use in %{....} or just in general.

2005-09-24

New: https:// now supported in plain text

As part of fixing Atom feeds to not break embedded https:// urls, I decided that we should support plaintext https:// URLs, like say https://bugzilla.redhat.com/.

DWiki should now support non-HTTP URLs much better in general (before, there were a number of problems and issued). You can even include mailto: links if you really want to.

Written 00:00:43 by cks.

(Previous 10 | Next 10)

Page tools: See As Blogdir, See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.