While working on adding aliases, I noticed that there are a number of
places (in SwikiBook, in PageFormatter) which make direct reference to
XMLSwikiPage. In particular, the SwikiBook page loading code. Now, as I'm
given to understand, Swikis are supposed to be (relatively) neutral wrt to
storage format (which is what the concrete subclasses of nuSwikiPage are
supposed to do). For me, this is particularly important since I'm
introducing a proxy type which needs to get loaded at the appropriate time,
but is otherwise quite unlike XMLSwikiPage (or even nuSwikiPage, I think).

(There is the further, future problem of what happens if the XML format
evolves.)

I'm not quite sure the best way to handle it. There's two problems, really:

1) Detecting the type of page stored in the files.
2) Instantiating the correct object on a file by file, page by page basis.

This is especially tricky, IMHO, given the possibility (nay, the reality)
of heterogenous and distributed swiki collections (hah! I *saw*
#pagesFromPath:parent: :)).

One thought I had was to look at the FileStream/Directory classes, and how
concreteFileStream worked, and emulating that. That's fine for generalizing
access *as long as* you have some determination of the particular concrete
kind you need. So the file stuff works since you generally want the class
corresponding to your hosting platform, and that information is available.

So, if we have homogenous Swiki pages, we could put the page class in the
settings file (heh, assuming we don't have any problems with *that* format
:)). Then nuSwikiPage>>fromPath:withId: or some such, could dispatch based
on the known page type.

(Hmm. Actually, I guess one would just change SwikiBook>>pagesFromPath:

... dir fileNames do: [:fName |
                (fName asLowercase endsWith: '.xml') ifTrue: ["XmlSwikiPage"
"This is dispatching on the file ending."
                        number _ (fName copyFrom: 1 to: (fName size - 4)) asNumber.
                        page _ XmlSwikiPage new.
                        page id: number.
                        page fromPath: (pathName, fName).
                        pages at: number put: page]].

To (with swikiPageKind being an ivar of SwikiBook):
        dir fileNames do: [:fName |
                (swikiPageKind isPage: fName) ifNotNil:
                        ["get number"
                        page := swikiPageKind new.
                        "etc"
Where #swikiPageKind gets instantiated from the setting file.)

Ooo. Ok, that's made me think. The current code does dispatch on individual
files, but I think putting that into NuSwikiPage>>fromPath: is better.
That'll return #nil if it can't make a page out of a file, and the
appropriately initialized instance if it can.

NuSwikiPage>>pageFrom: aFilename
        |page|
        NuSwikiPage allSubclassesDo: [:pageClass |
                (page := pageClass pageFrom: aFilename) ifNotNil: [^page]]
        ^nil

Or something to this effect.

The only hitch would be if certain files could be loaded into more than one
SwikiPage kind, or there were ambiguous criteria. But I think this is a
small price :)

Comments?

Cheers,
Bijan.

Reply via email to