Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic generation of infobox structure #121

Open
TaylanUB opened this issue Apr 22, 2024 · 3 comments
Open

Dynamic generation of infobox structure #121

TaylanUB opened this issue Apr 22, 2024 · 3 comments

Comments

@TaylanUB
Copy link

Is there a way to generate the infobox structure dynamically? For example, using Wikitext parser functions to generate the XML that specifies the infobox structure? Or maybe a Lua API of sorts?

Pseudo-code for example purposes; I know this doesn't work:

<infobox>
  <panel>

    <section>
      <label>First section</label>
      ...
    </section>

    {{#if: {{{has section 2|}}} | <!-- Conditionally add a second section to the panel. -->

    <section>
      <label>Second section</label>
      ...
    </section>

    }}

  </panel>
</infobox>

The reason I wish to have something like this:

I'm building an infobox for creatures in a video game. The "statistics" part of the infobox may contain multiple tabs per difficulty setting of the game, if the creature's stats change depending on difficulty. There's four difficulty options one can choose from, and it's annoying when the infobox lists four tabs with identical contents for some trivial creatures that always have the same stats.

@Williek11
Copy link

You can use the #tag magic word on <infobox> for this. Essentially what it does is that it processes any wikitext inside of it before handing it out to the extension. See for further information: https://www.mediawiki.org/wiki/Help:Magic_words#tag

So, your code could be rewritten as:

{{#tag: infobox |
  <panel>

    <section>
      <label>First section</label>
      ...
    </section>

    {{#if: {{{has section 2|}}} | <!-- Conditionally add a second section to the panel. -->
    <section>
      <label>Second section</label>
      ...
    </section>
    }}

  </panel>
}}

This also means that you can use other wikitext syntax like, for example, #invoke and templates in areas where they normally would be ignored by the extension. For example, you could abstract your section logic into another template, say Template:Infobox/1:

<section>
      <label>{{{number|1}}}th section</label>
      ...
</section>

... and then just call that template in your main function:

{{#tag: infobox |
  <panel>    
    {{Infobox/1|number = 1}}

    {{#if: {{{has section 2|}}} |
    {{Infobox/1|number = 2}}
    }}

    {{#if: {{{has section 3|}}} |
    {{Infobox/1|number = 3}}
    }}

    {{#if: {{{has section 4|}}} |
    {{Infobox/1|number = 4}}
    }}

  </panel>
}}

Note this may have some side-effects on areas where you'd normally use wikitext, e.g. in <default> and <format>, aswell as parsing it in places it normally wouldn't, although I can't imagine a practical example where this causes a negative effect.

@TaylanUB
Copy link
Author

TaylanUB commented Jun 1, 2024

@Williek11 Thanks for the tip. I've tried this out, but unfortunately it seems I would need to escape a daunting number of special characters. For example:

  • Every = needs to be escaped, e.g. with the {{=}} trick. That's in every single <data source="..."></data>.
  • XML tags that happen to be accepted as HTML tags by MediaWiki such as <section> also need escaping, e.g. as &lt;section&gt;.
  • More escaping needed for {{{variables}}} in <format> that are meant to be parsed by PortableInfobox, not the template expander. I think conventionally this is done via {{(((}} and {{)))}} which is such an eye-sore...
  • Likewise with things such as using {{#invoke: ... | ... | ... }} inside a <format> where not only the {{ and }} but also each | needs escaping.

It seems doable but... It's all a bit much.

I wonder if certain tags, like <section>, could be made to support an attribute that acts similarly to source, in the sense that it would check whether a template parameter of that name is provided, and if not, the whole tag is ignored. Perhaps it could be called if because source seems wrong in this context. Pseudo-code:

<infobox>
  <panel>
    <section if="hasSection1">
      ...
    </section>
    <section if="hasSection2">
      ...
    </section>
  </panel>
</infobox>

(And, ideally, if a <panel> ends up containing a single section after the processing of the if attributes, it would not be displayed as a panel but simply be replaced with the contents of the section.)

I'm working on a bunch of other things on my wiki already (like trying to make Extension:TextExtracts not break when using PortableInfobox) but maybe I'll attempt to implement this myself eventually.

@Williek11
Copy link

Williek11 commented Jun 2, 2024

  1. Most things don't actually need to be escaped, considering you're working on a single page. Take, for example, <default>{{text|{{{1|}}}}}</default>, where Template:Text is abc{{{1}}}, and {{{1}}} is, say, "test". What happens is that the wikitext gets expanded to whatever {{{1}}} is. Then, the expanded text gets passed on to the extension, resulting in <default>abctest</default>. I experimented with this, and I couldn't find a case where this leads to something breaking.
  2. You don't have to worry about HTML tags because they aren't processed. If, say, Template:< was <, then <section> is functionally identical to {{<}}section{{>}}, unless that tag is actually processed by an extension. While testing, the only issue I got was that <section>, outside of <infobox>, is used by Extension:Labeled Section Transclusion, so I had to escape that.

One issue, though, is that you can't actually abstract logic into another template easily with wikitext alone, mainly because arguments wouldn't be processed and that causes a mess. It could theoretically be done by creating a module that passes the parent's arguments to the child, or just manually aswell, but alas, that's outside the scope of this issue.

Onto the actual issue, I feel this would be a nice addition to the extension as my solution is, admittedly, a bit cheesy. Maybe it would be more convenient to use tag syntax with wikitext so we can use logic on the template? Or simply the ability to use wikitext in an attribute (although it would be fairly different from the rest of the syntax in the extension)? For example:

<infobox>
  <panel>
    <!-- no. 1 -->
    <section>
      <show>{{#ifeq: {{{class|}}} | mage | y}}</show>
      ...
    </section>
    <!-- or no. 2 -->
    <section if="{{#ifeq: {{{class|}}} | mage | y}}">
      ...
    </section>
  </panel>
</infobox>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants