-- itemlist-microdata Soupault Plugin -- SPDX-FileCopyrightText: 2026 toastal -- SPDX-License-Identifier: MPL-2.0 -- -- Numbers Soupault-generated feed lists (cookbook & manpage indexes). -- The per-item ListItem structure lives in the index_item_template in -- soupault.ncl; this plugin only scopes the list itself & stamps document -- order as position (Soupault sorts by headline — this never reorders): -- ul.Feed-items → mainEntity ItemList -- li.Feed-item → position meta (upserted, so re-runs are safe) Plugin.require_version("5.0.0") lists = HTML.select(page, "ul.Feed-items") if Table.is_empty(lists) then Plugin.exit("No feed lists on this page, nothing to do") end local idx = 1 while lists[idx] do local list = lists[idx] HTML.set_attribute(list, "itemscope", "") HTML.set_attribute(list, "itemprop", "mainEntity") HTML.set_attribute(list, "itemtype", "https://schema.org/ItemList") local items = HTML.select(list, "li.Feed-item") local jdx = 1 while items[jdx] do local item = items[jdx] local position = HTML.select_one(item, "meta[itemprop=\"position\"]") if HTML.is_element(position) then HTML.set_attribute(position, "content", format("%d", jdx)) else local meta = HTML.create_element("meta") HTML.set_attribute(meta, "itemprop", "position") HTML.set_attribute(meta, "content", format("%d", jdx)) HTML.append_child(item, meta) end jdx = jdx + 1 end idx = idx + 1 end