Template with variable number of parameters - mediawiki

I'm working on setting up a wiki for a small game and I'm facing a problem concerning templates.
Organization of the wiki :
This game has regions, which are made up of several levels. My wiki has one page for each region, and this page contains miniatures of each level, which link to the page for the level.
For now, I have something like this for my Level template :
|-
| [[Image:{{{region_images}}} {{{level}}}.png|200px|link={{{region}}}/{{{level}}}]]
And that's how it is used in a Region page :
{| style="text-align: center;"
{{Level|region=My Region Name|region_images=My Region Filename|level=0}}
{{Level|region=My Region Name|region_images=My Region Filename|level=1}}
{{Level|region=My Region Name|region_images=My Region Filename|level=2}}
{{Level|region=My Region Name|region_images=My Region Filename|level=3}}
{{Level|region=My Region Name|region_images=My Region Filename|level=4}}
{{Level|region=My Region Name|region_images=My Region Filename|level=5}}
{{Level|region=My Region Name|region_images=My Region Filename|level=6}}
|}
region and region_images would have been the same thing if this wiki supported non-UTF-8 characters in filenames, but unfortunately it doesn't.
Main problem :
So, as you can see, region and region_images are repeated everywhere, so I was thinking I could make a template to take care of it.
I was thinking of something I could use like this :
{{Region|name=My Region Name|region_images=My Region Filename
|0
|1
|2
|3
|4
|5
|6}}
that would generate the Level templates like in my previous example. But I'm pretty new to templates and I'm not sure if it's doable. It seems I would need a list of parameters of variable length in my Region template, but I can't find something like that. If it doesn't exist, how should I do it ?
Subsidiary question :
Actually, I simplified a bit the situation, but in this game levels can link to other levels, so I wanted to indicate it too in the region's page. The Level template has optional parameters, "prev" and "next". If they are used, then the template adds a note next to the miniature of the level.
If possible (if my main problem has been solved), I would like to keep these optional parameters and be able to do something like :
{{Region|name=My Region Name|region_images=My Region Filename
|0
|1 |prev=Another region
|2 |next=Yet another region
|3
|4 |prev=Another region |next=Yet another region
|5
|6}}
Obviously, when I have one Level template for each level, it's easy to do, but with this Region template, I could not have more than one "prev" or "next" parameter, if my understanding is correct.
Thanks in advance for your help, feel free to ask any questions if something was not clear enough !

You can install ParserFunctions and do something like this:
{{Region|name=My Region Name|region_images=My Region Filename
|0
|1 |prev1=Another region
|2 |next2=Yet another region
|3
|4 |prev4=Another region |next4=Yet another region
|5
|6}}
and put this into the Region template:
{| style="text-align: center;"
{{#if:{{{0|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=0|prev={{{prev0|}}}|next={{{next0|}}} }} }}
{{#if:{{{1|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=1|prev={{{prev1|}}}|next={{{next1|}}} }} }}
{{#if:{{{2|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=2|prev={{{prev2|}}}|next={{{next2|}}} }} }}
{{#if:{{{3|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=3|prev={{{prev3|}}}|next={{{next3|}}} }} }}
{{#if:{{{4|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=4|prev={{{prev4|}}}|next={{{next4|}}} }} }}
{{#if:{{{5|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=5|prev={{{prev5|}}}|next={{{next5|}}} }} }}
{{#if:{{{6|}}}|{{Level|region={{{name}}}|region_images={{{region_images}}}|level=6|prev={{{prev6|}}}|next={{{next6|}}} }} }}
|}

Related

Conditional categories

I'm using a template {{MyTemplate|foo}} which consists of the following code:
{{#switch: {{{1}}}
| foo = [[Category:Foo]]
| bar = [[Category:Bar]]
| #default = [[Category:Unknown]]
}}
When I'm using it on a page, the categories show up nicely as wished at the bottom of that page. But unfortunately inside of that category-page (Category:Foo for example) the page doesn't show up.
If I add [[Category:Foo]] manually to that page, the page shows up in the Foo-category-page.
Any suggestions why this doesn't work via the template?
Does the template page that contain the previous code appear under Unknown category?. If yes, then any page contain that template must appear in it's category. You may just have to clear cache, and wait few seconds if you have a large wiki.
Make sure that foo & bar categories are not hidden in your wiki. See this: https://www.mediawiki.org/wiki/Help:Categories#Hidden_categories
EDIT
Also, try one of these solutions, which can do the same goal:
{{#switch: {{{1}}}
| foo = [[Category:Foo]]
| bar = [[Category:Bar]]
| #default = [[Category:Unknown]]
}}
OR
{{#ifeq: {{{1}}} | foo | [[Category:Foo]] | {{#ifeq: {{{1}}} | bar | [[Category:Bar]] | [[Category:Unknown]]}} }}
Do you run the jobqueue on your wiki? Linkstables are updated asynchronously and not at page save time.
https://www.mediawiki.org/wiki/Manual:Job_queue
https://www.mediawiki.org/wiki/Manual:RunJobs.php
Cant understand the description to your problem, but anyway, it seems like you could achieve the same goal by:
{{#vardefine: my_category |wow}}
[[Category: {{#ifeq: {{#var:my_category}}| default| unknown| {{#var:my_category}} }} ]]
Which adds this category to the page,
In my opinion, you should use switch when you are adding category in any case but also decide not to add category in another case.
If you are adding category in all cases, you can write as i wrote above, or export the final category to another variable and use it inside the category.
As for your problem, you can use "?action=purge" for this page, if that wont work, write here some more info.

How to use Wikipedia's API to scrape only the template:Infobox Automobile

I'm trying to scrape the helpful Infobox from most Automobile pages, however I'm messing up the syntax. From other helpful SO posts, I've found a handy method of scraping a standard Infobox template (the example given was for hydrogen):
https://en.m.wikipedia.org/w/index.php?action=raw&title=Template:Infobox%20hydrogen
I can use a similar process to pull the Ford Pinto page (using this as it only has a single Infobox, as there was only one, infamous, model generation):
https://en.m.wikipedia.org/w/index.php?action=raw&title=Ford_Pinto
This page, and most automobile pages, used one of the vehicle-specific Infobox templates, in this case "Infobox automobile" (sorry for the massive block, I'm going to edit this once it's posted as I'm on mobile and I read up on SO formatting):
{{Infobox automobile
| name = Ford Pinto
| image = Ford Pinto.jpg
| caption = Ford Pinto
| manufacturer = [[Ford Motor Company|Ford]]
| aka = Mercury Bobcat
| production = September 1970–1980
| model_years = 1971–1980 (Pinto)<br> 1974–1980 (Bobcat)
| assembly = '''United States:''' {{ubl|[[Edison, New Jersey]] ([[Edison Assembly]])|[[Milpitas, California]] ([[San Jose Assembly Plant|San Jose Assembly]])}}'''Canada:''' {{ubl|[[Southwold, Ontario]] ([[St. Thomas Assembly]])}}
| designer = Robert Eidschun (1968)<ref name=bbw20091030>
...
Snipped some useless stuff
...
</ref>
| class = [[Subcompact car]]
| body_style = 2-door [[Sedan (automobile)|sedan]]<br/>2-door [[sedan delivery]]<br/>2-door [[station wagon]]<br/> 3-door [[hatchback]]
| related = [[Ford Pinto#Mercury Bobcat (1974–1980)|Mercury Bobcat]]<br>[[Ford Mustang (second generation)|Ford Mustang II]]<br> [[Pangra]]
| layout = [[Front-engine, rear-wheel-drive layout|FR layout]]
| engine = {{unbulleted list
| 1.6L ''[[Ford Kent engine|Kent]]'' I4
| 2.0L ''[[Ford Pinto engine|EAO]]'' I4
| 2.3L ''[[Ford Pinto engine|OHC]]'' I4
| 2.8L ''[[Ford Cologne engine|Cologne]]'' V6
}}
| transmission = {{unbulleted list
| 4-speed manual
| 3-speed ''[[Ford C3 transmission|C3/"Selectshift/Cruise-O-Matic"]]'' automatic
...
Snipped
...
</ref>
|wheelbase = {{convert|94.0|in|mm|abbr=on}}<ref>
...
Snipped
...
}}
| wheelbase = {{convert|94.0|in|mm|abbr=on}}<ref>
...
Snipped
...
</ref>
| length = {{convert|163|in|mm|abbr=on}}
| width = {{convert|69.4|in|mm|abbr=on}}
| height = {{convert|50|in|mm|abbr=on}}
| weight = {{convert|2015|–|2270|lb|abbr=on}} (1971)
| predecessor = [[Ford Cortina|Ford Cortina (captive import)]]
| successor = [[Ford Escort (North America)|Ford Escort]]
}}
Though not as pretty as the above, another alternative is to use the REST API and slim the page down to just the article, in HTML, which will let me use a standard HTML parser to pull just the Infobox HTML table (link should work in chrome, but will definitely work on an Android device):
view-source:https://en.wikipedia.org/api/rest_v1/page/html/Ford_Pinto
<table class="infobox hproduct" style="width:22em" about="#mwt7" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Infobox automobile\n","href":"./Template:Infobox_automobile"}
I can handle parsing either of these for the information I want, namely performance information - model, years, drivetrain layout, engines, transmissions, wheelbase, weight - however despite trying various API/other urls, I've yet been unable to directly scrape just the Infobox using the API alone. Also, I'm not exactly sure what the difference is between using an api.php? action=parse url vs an index.php? action=raw - any clarification here is welcome, though I don't think directly relevant. Here are some unsuccessful examples of what I have tried, each with different errors/results:
https://en.wikipedia.org/w/ <- append the following to this base link as I can't post a bunch of links
api.php?action=parse&page=Template:Infobox%20automobile%20Ford_Pinto&format=json
api.php?action=query&titles=Template:Infobox%20automobile%20Ford%20Pinto&prop=revisions&rvprop=content&format=json&formatversion=2
api.php?action=query&titles=Template:Infobox%20automobile%20Ford_Pinto&prop=revisions&rvprop=content&format=json&formatversion=2
index.php?action=raw&title=Template:Infobox%20automobile%20Ford_Pinto
index.php?action=raw&title=Template:Infobox%20automobile%20Ford%20Pinto
index.php?action=raw&titles=Template:Infobox%20automobile%20Ford_Pinto
index.php?action=raw&titles=Template:Infobox%20automobile%20Ford%20Pinto
This is different from various other Infobox scraping questions as these articles use a specific Infobox template that prevents me from using the very successful API url I've posted above, although I'm sure this is user error and a simple fix. Thank you for your time in reading and assisting!
Edit: the suggested page is the way I'm already trying, and failing. Per that page, I am attempting the 'wrong' way until someone, including myself, figures out what I'm doing wrong - assuming there is a right way for the non standardized/base Infobox Templates. Failing any new information in a day or so, I'll just accept the currently suggested answer to reward that user's helpfulness - but I really hoped I'd get a few more attempts, which is why I created an account and asked the hive mind after searching and failing to find an answer from the many other questions I checked. By the way, any attention is good attention, so thank you kindly for taking the time to look over this!
Wikipedia infoboxes are not designed to be scrapeable. They are primarily a (front-end!) templating mechanism; the fact that they sometimes contain structured data is incidental.
The difference between action=raw and action=parse is simply that raw gives you the original wikitext (like you'd see if you clicked the "Edit" link on the article), and parse gives you the rendered HTML. Neither of these is likely to be much use for your purposes.
Your best bet will be to use data from a downstream project like DBpedia which has already done the dirty work of parsing these articles. For instance, here's their parsed data for the Ford Pinto:
http://dbpedia.org/snorql/?describe=http%3A//dbpedia.org/resource/Ford_Pinto
You could use the Parsoid output of the page https://en.wikipedia.org/api/rest_v1/page/html/Ford_Pinto, which has a table with class infobox and a data-mw with some JSON encoded data.
I would look for the infoboxes (CSS selector table.infobox) and run a JSON.parse on the data-mw value. Check if the infobox has href ./Template:Infobox_automobile then look for the right parameter (in the params field).
Here's a sample request:
curl -X GET --header 'Accept: text/html; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/HTML/1.6.1"' 'https://en.wikipedia.org/api/rest_v1/page/html/Ford_Pinto'
In addition to the Accept header it's also good to set the User-Agent header to a unique string.

Semantic mediawiki #ask query: Displaying nested properties on the same query

I would like to display in the same query properties of a page which is related to the pages im querying for.
Let's say I would like to query all the pages in the City category, which are located in Germany, and I want to display the title of the page, but also I want to display the surface data of Germany, for example.
Something like this: {{#ask: [[Category:City]] [[location::Germany]] |?mainlabel |?Location.surface }}
I know this wont work, but you can see what I want to achieve.
I'm not sure if there's a way to nest queries directly inside other queries. The normal method of doing it is using a template. So you might define a template (or subpage of the template if this going into a template) called {{tablerow}} that consists of:
<includeonly>
|- valign="top"
| [[{{{1|}}}]]
| {{#show: {{{1|}}} | ?surface }}</includeonly>
The <includeonly> tags are important for reasons I don't really understand, it produces errors sometimes if you leave them out. Then you just run an #ask query with format = template. (You can build the header into the query, but I find it simpler to just put it outside.)
{| class="wikitable smwtable sortable"
|- valign="bottom"
! [[City]]
! [[Surface]]
{{#ask: [[Category:City]] [[location::Germany]]
| format = template
| template = tablerow
| link = none
}}
|}
That will punch each result returned by the query through the template as {{{1}}} and generate a row based on it. If you have other data to return from the main query, additional properties that you ask for will come out as consecutive unnamed parameters (so if you include | ?population, that will go into the template as {{{2}}} and will need to be added to the row structure or it will be dropped).

How to select an option in multiple select box and load data from selected option

I am trying to figure out how to load data from a selected option.
For example, in the multiselect dropdown box I have 3 options:
Option 1: Apple
Option 2: Orange
Option 3: Pear
Let's say I have a data list for each option. For example when I choose Apple,
It will load a table in an inner div describing its price, weight and country on the first column.
When I choose the 2nd option, it will allow me to compare it with the 1st option. It should load on the 2nd column.
For example:
Option : Apple | Orange
Price : $3.95 | $2.50
Weight : 40g | 50g
Country : USA | Brazil
Would be great to know what the ideal language/method is for this?
JavaScript / jQuery ?
Edit : Sorry if there's any confusion, my main question was how to do what I just described?
I would highly recommend that you use jQuery for this. Among other things, jQuery has excellent documentation.

How to represent invisible name-value pair data associated with HTML table row?

Background
I am presenting data using a HTML frameset. The left-side frame is a navigation tree-table constructed as an HTML table. Only minimal data is shown in this frame because I want to use the right-side "details" frame to give the user more details when he selects one of the navigation table rows.
+----------------------------+
| | |
| tree | "details" |
| table | pertaining to |
| nav. | selected |
| | row |
|=selected=| |
| | |
| | |
| | |
+----------------------------+
Think of this like a directory browser where you can see filesize, type, modification date, etc. on the right when you select an item in the left-hand tree.
Obtaining item details server-side is a sequential task, i.e. to get details on the nth item, the server has to work through all n-1 preceding items. For this reason, I think the most straightforward way to present the detailed data to the user is to have the server embed all detailed information within the navigation table rows and have a script generate the details page in a right-hand frame.
Question
How should I represent the detailed data within the navigation table HTML? Should I make up my own element tagnames? Should I use extra columns that are not displayed? Or something else? The data is typically name-value pairs - both name and value can be text. Each element may have a different set of data pairs. Is there a standard way to represent user data within an (X)HTML document?
NEVER, EVER EVER EVER EVER EVER EVER mix data and display. I also think you can easily get around the iterating over n elements to get the data you require. Here is how you do it.
Create a model (your data storage) in the javascript.
var data = [
{
title: "item 1",
foo: "bar",
baz: 10
},
{
title: "item 2",
foo: "bazbar",
baz: 20
}
];
Then, using Javascript, you could use the above data to create the following table on the left
<table>
<tr><td>item 1</td></tr>
<tr><td>item 2</td></tr>
</table>
So then you would have your show details function
function showDetails(index){
var currentData = data[index];
/* Do something with data */
}
I have created a working example here. There is an error in that code that says showDetails is not defined, but that is due to a jsfiddle issue, the code will work if put into a HTML page. ALSO, be sure to use the strict doctype at the top (to avoid cross browser quirsk).
Might I also suggest, that you look at YUI 2's layout manager instead of using a frameset. Framesets require multiple pages with javascript snaked throughout and can be a maintenance nightmare down the road.