Previous Entry Share Next Entry
Release 1.2.8: Trees!
jducoeur wrote in querki_project
My primary focus continues to be Apps; this week is sort of side-effects from that. Specifically, the Extract an App UI needed a decent "tree"-styled control for selecting the Models and Instances to pull into the App. As is the usual style for Querki, I'd rather not hardcode anything for application use without making it available to end users. That more or less drove all of this week's enhancements.


The most indirect of these enhancements is the geekiest, and only of interest to the programmers, but it's something I've been wanting for 18 months now: QL now supports named parameters. This is a really big deal when it comes to making QL functions easier to use.

QL has had optional parameters from the beginning, but they're always been positional: if you wanted to specify the fourth parameter, you had to also give the third one. This wasn't a big deal for most functions, since most of them had at most one optional parameter. But when I got to the new _thingTree function (discussed more below), it was a big problem: _thingTree takes five parameters, *all* of them optional. So simple positioning wasn't going to cut it -- you needed to be able to specify just a single parameter or two, as needed, without worrying about what order they're supposed to be in.

The new mechanism has exactly the syntax you'd expect from most programming languages:
[[My Model -> _thingTree(opened=False, children=_instances -> _thingTree)]]
That is, you say "name=value", in whatever order, and it just works. Note that this works even though all parameters are allowed to be full QL expressions, as always -- I've known for a couple of years that this enhancement was coming, and it's why "=" has never been used for anything else in QL. (Assignment will be added eventually, but has a different syntax.)

Note that named parameters are only for system-defined functions so far; I haven't yet added the UI for naming the parameters in user-defined functions yet. That'll come in due course -- the mechanism "plays fair" in the usual Querki style, so that it can be exposed to user functions. (It is actually based on a bog-standard, if very complex, Model Type.) I just think that it needs a bit of custom spit and polish to make the UI usable for user-defined functions, and haven't had time for that yet. Yell if you find yourself really wanting this.

Along with that, notice the nice new documentation for _thingTree? The implementation of named parameters is handled through the new Signature type, a structure that describes the full signature for a function. If a function has a Signature, it gets displayed this way, with proper documentation for each parameter, as well as the received context. Only a few functions have Signatures yet, but the plan is to redo all of the system-defined functions this way before long.

(In the longer term, these Signatures will eventually be used to make Querki *much* more strongly-typed. The hope is that we'll even be able to eventually have a decent IDE in the browser, automatically telling you as you type if your QL expressions are illegal.)

As for _thingTree itself, that was kind of the point of the exercise: I needed to integrate a proper tree control, so decided to start by putting them into the main system. This shows up most immediately as a *major* change to the UI: the All Things view, shown by default as the main display of the Space, is now shown as a Tree. The look is somewhat similar to the way it was before, but you can now open and close the Models of this tree; this helps to tame the sheer amount being displayed at once. (It also means that the initial display is often much faster than it was before.)

An important aspect of this is that most Instances are not displayed by default. The All Things view shows the root Models in your Space, but the only Model that is opened by default is Simple Thing. This means that your top-level Models are shown, as well as your main Pages (that derive from Simple Thing), but not all of your Instances. I *think* this is broadly best, but we'll see how it works out. It does provide a bit of incentive to build a custom front page for your Space, which is often ideal anyway, but we'll see if that proves to be too much work for people. This decision is probably the most tentative part of everything I've done this week -- opinions are solicited, especially as you play with the new environment and get a feel for what it's like.

That new All Things view is simply an ordinary QL expression, built out of the new _thingTree function. _thingTree, as the name implies, builds a tree of Things. In the All Things view, that's showing the Model/Instance hierarchy, but the tool isn't limited to that. The notion is that _thingTree() creates a node for a single Thing, and optionally specifies a QL expression giving the children of that Thing. (For now, this expression needs to return _thingTrees for each child; I may make it smarter later.)

This makes it easy to build arbitrary hierarchies. For example, in the Lochleven Inventory Space that I manage, I just whipped up an Items by Location tree, which looks like this:
[[Housing._instances -> _thingTree(children=Housed Where._refs -> _thingTree)]]
That is, show a tree root for each Instance of "Housing" (where something is located); for its children, return the Items that are housed there.

I hope folks find this easy to use. Give a yell if you have problems.

Finally, a more minor enhancement that I happened to need in one of my Spaces: _QLButton now has an optional "append" flag. The _QLButton and _QLLink functions produce a button or link that, when clicked, displays the result of some QL expression. This is the basis of lots of functionality, and the standard UI uses it a bunch. By default, if you click that button or link *again*, it hides the displayed bit. If you add "append=true", though (another example of a named optional parameter), pressing the button or link again will run the QL again and append the results to the display.

I expect this to mainly be useful in "create" situations, especially when using _createHere: if you've got a button to create and edit a new Thing, you can now click it again to create more of them.

Bug fixes

Adding a comment to a dormant Space was giving an error. That is, if you left a tab open to a Space for a long time, so that the Space timed out on the server (which happens in about half an hour currently), and the *first* thing you did coming back to that Space was to add a comment in that tab, it wouldn't work. (Subsequent comments would be fine.) This was pretty straightforward -- the request to add the comment wasn't being stashed away while the Space booted up, so it was simply getting dropped on the floor.

Display Names were getting over-escaped in page titles and Search Results. If your Thing's Display Name contained XML-significant characters, they would get over-escaped -- for example, " would show up as ". This regression was a side-effect of the recent enhancement to make Computed Names work more generally. I've fixed it in those two spots; please give a yell if you observe other areas where this is happening. (There was a subtle API change involved, so other related bugs are possible.)

Duration editing was broken. Possibly editing of other "internal" properties was also broken, but this was the one I noticed. This regression was caused by a slightly-overzealous attempt to hide a Property that should never be end-user editable. I put a more subtle fix in place for that, that doesn't stomp on editing Duration and other such system-defined Model Types.


Log in

No account? Create an account