Topic on Talk:Parsoid/Extension API

Question about StructuredNavigation extension with custom content model and related extension tag

6
Summary by SSastry (WMF)

Parsoid API has adequate support for this extension and use case

SamanthaNguyen (talkcontribs)

Hello Parsoid developers,

I was looking at the Wikitech-l email regarding Parsoid, so I would like to mention my use case. I have an extension I maintain called StructuredNavigation. Here is it how it works:

  1. It implements a custom content handler that extends the default JSON content handler, in the Navigation namespace. This is where data for "navigations" go, which is intended as another way of writing navboxes with JSON instead.
  2. The user writes JSON in the Navigation namespace.
  3. The user uses the MW extension-registered parser tag, which requires one attribute, which must be a valid title name in the Navigation namespace.
  4. The JSON is retrieved from that page in the Navigation namespace, which is then transformed to HTML with CSS loaded with ResourceLoader.

So for example:

  1. A page is created at Navigation:Dontnod Entertainment.
  2. A wiki page is created, with the content: <mw-navigation title="Dontnod Entertainment" />.
  3. They press submit.
  4. The JSON is retrieved, processed, and then transformed to an HTML navigation box on final output.

I'm aware that this use case of how this parser tag is being used is probably unique among many extensions. From what I could tell, this use case didn't follow under any of the ones already listed. If the team can confirm that it does not follow under any of the 4 listed, is this something that could also be planned to add support for?

To note, this parser tag doesn't accept any text inside; it is a self-closing parser tag. If the title that the user passes doesn't exist, there is simply no HTML rendered instead.

SSastry (WMF) (talkcontribs)

Thanks for checking in about this.

Parsoid supports ContentModelHandler extensions and they need to extend the Wikimedia\Parsoid\Ext\ContentModelHandler class. So, in your case, the code that implements that ContentModelHandler support will need to implement the toDOM and fromDOM methods. For example, the check the JSON extension.

As for the parser tag, when Parsoid calls your tag's sourceToDom method (which you will need to implement), that code will need to do whatever you are doing now to retrieve the content of the Navigation:$titleAttr page and process it - that is probably going to invoke your content model handler's toDOM method. So, that will be return value of the sourceToDom method (you will probably also update the ParserOutput object to register modules, etc.).

That is a somewhat handwavy response for now, but yes, I don't see anything in your use case that won't be supported.

If we discover any API gaps, we can figure out and fix those gaps.

SSastry (WMF) (talkcontribs)

One question is whether the ParsoidExtensionAPI object has API methods for you to retrieve the Navigation namespace content (if that is needed). And, once you retrieve it, the other question is whether you are going to go through Parsoid to convert your non-wikitext content or short-cut it internally by calling your extension's code.

If the former, we need to make sure that ParsoidExtensionAPI::extTagToDOM method has options to specify the content model OR we need to provide an alternate method to convert non-wikitext content models to DOM.

SSastry (WMF) (talkcontribs)

But to go back to your comment, we could consider your ext-tag as either type 1 or type 3 in that categorization depending on whether we treat custom content models as "wikitext" or not.

SamanthaNguyen (talkcontribs)

Thank you SSastry, that helps. It looks like it does; I could use ParsoidExtensionAPI::makeTitle() by passing the user title into the first parameter, and pass in the Navigation namespace ID into the second parameter.

I would most likely do the latter (calling my own code), since I am already doing that right now.

Thanks for the clarification :)

SamanthaNguyen (talkcontribs)

For clarification, currently the extension:

  1. attempts to construct a Title object from that passed title string by the user (will return early if Title::exists() returns false)
  2. Then it constructs a WikiPage from the Title object
  3. Then retrieves the Content from the WikiPage, by calling WikiPage::getContent()

So in short/tldr, the former method to use Parsoid doesn't seem to be needed for this extension.