Working With MediaWiki
ingredient::tomatoes]]
”, but a tag like “
[[Has quantity::3]]
” wouldn’t work — it wouldn’t be clear which ingredient that applies to. So you could create a separate page for each row; but this would lead to a large number of pages — 10 or more for each recipe — that could easily become overwhelming. (To take one example, if you wanted to delete a recipe, you would have to delete all the ingredient pages for it.) Nearly as bad, there’s no obvious naming system to use for each ingredient page — you would have to go with something along the lines of “Lasagna recipe tomatoes row”, or, even more cryptically, “Recipe row 73411”. In any case, maintaining all these pages could become a nightmare.
Instead, the recommended solution is to store all this information (in this example, the entire recipe) in a single page. There are two approaches that allow this: the #subobject parser function, and the Semantic Internal Objects extension. The two have a slightly different syntax, and a different approach toward storage.
Subobjects
#subobject is a parser function defined by Semantic MediaWiki, that lets you store compound data of this sort. A call to #subobject is defined as:
{{#subobject:subobject name |property 1=value 1 |property 2=value 2 |...}}
For the original example, in a page called “Greek salad”, you could have a call to #subobject that looks like:
{{#subobject:Tomatoes row |Has ingredient=tomatoes |Has quantity=3}}
The special property “Has subobject” is then stored, pointing from the page to the subobject.
To display all the rows in this recipe from another page, you could run a query like this one:
{{#ask:[[-Has subobject::Greek salad]] |?Has ingredient |?Has quantity |mainlabel=-}}
Note that the query for “Has subobject” is done using an inverse property.
Why is “
mainlabel=-
” in there? Because here, as in many cases, there’s no reason to display the name of each row (e.g., “Tomatoes row”).
To show all the recipe pages that call for at least two tomatoes, you could run this query:
{{#ask:[[-Has subobject::[[Has ingredient:tomatoes]][[Has quantity::>2]]
}}
There’s another helpful feature of #subobject: if you leave the first parameter, i.e. the subobject name, blank, then the subobject gets assigned an arbitrary random name. That way, you don’t need to assign a name to each one. So you could instead call:
{{#subobject: |Has ingredient=tomatoes |Has quantity=3}}
Being able to call #subobject without an assigned name is extremely important when it’s called from a template — which, as we’ll see in the next chapter, is how it’s usually called.
There’s one more important aspect of calling #subobject, which is that it’s almost always a good idea to include a property pointing back to the page it’s on. So the ideal version of this call might be something like:
{{#subobject: |Has ingredient=tomatoes |Has quantity=3 |Is recipe in row={{PAGENAME}} }}
You can see why adding that last property, “Is recipe in row”, is helpful, when you see the query that this enables us to call:
{{#ask:[[Is recipe in row::Greek salad]] |?Has ingredient |?Has quantity |mainlabel=-}}
This version of the query is both more logical and more “semantic”.
Semantic Internal Objects
The Semantic Internal Objects extension provides a similar, though not identical, approach to storing compound data. It defines a parser function, #set_internal, that holds what it calls an “internal object” within the page that has semantic properties of its own, as well as a property that links the object back to the page. Any number of internal objects can be defined for a single page. A call to #set_internal is defined as:
{{#set_internal: object-to-page property |property 1=value 1 |property 2=value 2 |...}}
With Semantic Internal Objects (SIO), objects are never given a name -- a name is arbitrarily assigned to each one, that’s not meant for display. And there’s a specific parameter for setting the property pointing from the object to the page.
Let’s see how this works in action. For the original example, in the page called "Greek salad" you could have a call to #set_internal that looks like:
{{#set_internal:Is row in recipe |Has ingredient=tomatoes |Has quantity=3}}
The query to get all the rows in a single recipe is then identical to the last one we saw for #subobject:
{{#ask:[[Is row in recipe::Greek salad]] |?Has ingredient |?Has quantity |mainlabel=-}}
The
Weitere Kostenlose Bücher