Anno 1800 Wiki
Advertisement
Anno 1800 Wiki

This wiki's data structure problem[]

This wiki has a data structure problem. We do not lack data, we have Production chains, we have Buildings, we have Items. Neither do we have a data presentation problem, we have Template:Chain and Template:Infobox Buildings Old and New World and Template:Item box, which are all wonderful ways to present the information we have.

However, they are difficult to match together. There are many small pages on this wiki that want to show a specific subsection of this data, but they cannot. More often than not, there is simply a reference to the big list, with an implicit "go find it yourself" message for the end user. Other times, the editor has simply crafted their own data element. This will not do.

This will not do[]

To this end, the repository template is a concept. It has already been successfully applied to production chains, with Template:PCList. Now, if you want to show the end user the production chain for Sewing Machines, you do not stubbornly write a Chain call yourself. If you get anything wrong, there will be a mismatch of conflicting information on the wiki, which is a mess and a half to keep track of. Nor do you idly link to the big list. Instead, you type

{{PCList|Sewing Machines}}

and you find:

Sewing MachinesSewing Machines

Balance -1310Farmers 5Workers -300Artisans -300Attractiveness -10

Credits 26500Timber 28Bricks 40Steel Beams 16Windows 16

The Coal Mine Coal Mine may be replaced with two Charcoal Kiln Charcoal Kilns
for  Balance +10Workers +30Attractiveness -10Credits -400Timber -4Bricks +5

Supplies:
  • 140 Artisans Artisans Residences (up to 4200 Artisans Artisans)
or 70 Engineers Engineers Residences (up to 2800 Engineers Engineers)
or 160 Obreros Obreros Residences (up to 3200 Obreros Obreros)

comes out on the page. Wonderful. If only one could simply call an

{{Item box|Lumberjack}}

as easily. What do you know, you can (sort of). By typing

{{item|Lumberjack}}

you find

Template:Item

on the page. Sadly, this only works for Common Trade Union items so far. The intent is to replace all the big lists on this wiki, all the item lists, the ship list, etc, with repository templates appropriate for that type.

How does this work?[]

The repository template is a wiki trick that builds on a concept known as transclusion. Transclusion is the act of copying (part of) one page on a wiki into another page, but dynamically. That way, any change on the original page also appears on the copying page. This fundamental technique is used by every template. What makes this interesting is the way the Template builds on transclusion by also accepting parameters back. These parameters can then be interpreted by parser functions to hide or show parts of the transcluded page to leave visible whatever the transcluding page needs.

What this all amounts to is effectively the same big list page as we already had, but it only shows the element the parameter asks for. The editor of small pages can now effortlessly show any element of the big list they want, and they get exactly and only the elements they want to show the end user, all details correctly filled in the appropriate data presentation template.

How does this work, in detail?[]

This will get technical, so strap in. I will try to motivate things, but it won't be easy. For the sake of simple examples, say we had a template named

{{thing|a|b|c}}

with 3 parameters, a, b, and c. We have 2 combinations of those parameters we want to present. How do we do this? Easily:

{{thing|1|2|3}}
{{thing|3|2|1}}

But now comes the interesting question, how do we ONLY show the first combination IF the parameter we get is "APPLE", and ONLY show the second combination if the parameter we get is "BANANA"? As follows:

{{#ifeq: {{{1}}}|APPLE|
    {{thing|1|2|3}}
|}}
{{#ifeq: {{{1}}}|BANANA|
    {{thing|3|2|1}}
|}}

Let's break that down. What we just did is take the {{thing}} calls up there, and surrounded each in an "#ifeq:" parser function. Then we asked each parser to look at the first parameter ("{{{1}}}") and compare it against the required parameter "APPLE" or "BANANA". If the parameter is equal to the fruit, the first option is shown, which is our template call. If it is not, the second option is shown, which is simply nothing in our case. This will result in the page as a whole showing the first option of the first parser and the second option of the second parser if the parameter is "APPLE", the second option of the first parser and the first option of the second parser if the parameter is "BANANA", and the second option of both parsers if the parameter is neither.

This format is useful because you can intersperse it with navigational aid.

==APPLE==

<onlyinclude>{{#ifeq: {{{1}}}|APPLE|
    {{thing|1|2|3}}
|}}</onlyinclude>

This will show Apple.

==BANANA==

{{#ifeq: {{{1}}}|BANANA|
    {{thing|3|2|1}}
|}}

This will show Banana.

However, if you do not need navigational aid in your repository page, you can do something a little smarter: use a switch:

{{#switch: {{{1}}}
|APPLE  = {{thing|1|2|3}}
|BANANA = {{thing|3|2|1}}
}}

The switch parser function is easier to read and better on performance, but cannot be interrupted with user facing text. Note on using the switch: make sure to nest them if you have more than 100 cases. A single split on 200 is slower than 2 nested splits with =<100 each. Another downside of the switch method is that you cannot do the following:

Now for the hard part[]

Say you want to show the first combination if the parameter is "APPLE" or "BANANA", and the second combination if the parameter is "CITRUS" or "DATES"? The straightforward way is repetitive, but there is a better way, although it is harder to follow:

{{#ifexpr: ({{#ifeq:{{{1}}}|APPLE|1|0}}) or ({{#ifeq:{{{1}}}|BANANA|1|0}})|
    {{thing|1|2|3}}
|}}
{{#ifexpr: ({{#ifeq:{{{1}}}|CITRUS|1|0}}) or ({{#ifeq:{{{1}}}|DATES|1|0}})|
    {{thing|3|2|1}}
|}}

What is going on? The first step is looking at the components. First we ask 2 questions:

Q1: {{#ifeq:{{{1}}}|APPLE|1|0}}
Q2: {{#ifeq:{{{1}}}|BANANA|1|0}}

Here, we ask the "#ifeq:" parser to tell us if the parameter is "APPLE", and give us the boolean TRUE if it is. Then we ask the second parser the same, but for "BANANA". Then we ask for the Logical OR of these 2 booleans as follows:

({{#ifeq:{{{1}}}|APPLE|1|0}}) or ({{#ifeq:{{{1}}}|BANANA|1|0}})

As long as the parameter is either "APPLE" or "BANANA", this will result TRUE. Then we ask the final "#ifexpr:" parser to look at the resulting boolean and give us the {{thing|1|2|3}} call if it is TRUE. We do the same for "CITRUS" and "DATES" to result {{thing|3|2|1}}. This is how you show the same combination for different parameters.

So that's it?[]

In a nutshell, that's the core of it. Take heed though, that it often turns out far pricklier in practice. Not only are the element template calls far longer than in my example, but you will often find whitespace stacking a big issue. Make sure to hide line breaks in html comments (<!-- and -->) and look out for included empty lines.

Intermediate repositories[]

One more concept I want to touch on are intermediate repositories. These use the main repositories and craft sublists based on certain types of categorisation, so the end editor does not need to craft the sublists manually. If you only need a single element, directly using the main repository is easy enough, but if you need 20 elements, the intermediate repository is a great middleman.

Where are these used?[]

Currently, only Template:PCList is fully operational. I am currently working on Template:item to expand it into all trade union items, and then all items. I will also make use of intermediate repositories so the individual building pages can directly reference the list of items their building is affected by. Ships should also be repositorized, but I am not aware of a data presentation template for ships yet. Same for Goods Perhaps other big data sets can be repositorized too, but I don't see as much demand or opportunity elsewhere. Feel free to use repositories and perhaps make some on your own initiative.

Advertisement