Global Lua Modules/ModularCSS

ModularCSS is a Lua module that can replace modular portions of a wiki's cluttered CSS code with an imported stylesheet generated server-side through simple bulleted list configuration pages.
This script is best used as a way to quickly deploy minor, yet bulky CSS edits with minimal effort or as a way to provide easy wiki customization for those less adept utilizing CSS. Further uses include letting non-sysop wiki staff modify non-essential CSS through the sandboxed configuration pages.
== Installation ==
=== Base Install ===
The basic install comprises of prepping the base module for use on your local wiki. Sub-modules will need to be imported later as the standalone base module lacks any functionality.
==== Step 1: Importing the base module ====
This module should be installed locally in a page titled Module:ModularCSS. This module page should be fully edit protected as to prevent unauthorized changes to the wiki's CSS. (See w:Help:Page protection#Step by step for help protecting the page.)
The content of the page should comprise of the following:
return (require "Dev:ModularCSS")
==== Step 2: Creating the rendering page ====
The generated CSS code will need to be rendered on a local wiki page. It is suggested that the host page be located at MediaWiki:Custom-ModularCSS-render (or another page in the MediaWiki namespace), as this will prevent local editors from modifying the page and compromising the wiki's CSS.
The selected host page should comprise of the following:
{{#invoke:ModularCSS|render}}
==== Step 3: Importing the stylesheet ====
Now that the stylesheet has been generated at your selected rendering page, it will now need to be imported on your wiki's local MediaWiki:Common.css. Add the following to the very top of the page:
@import "/index.php?title=MediaWiki:Custom-ModularCSS-render&action=raw&templates=expand&ctype=text/css";
The above @import statement will need to be modified if the rendering page is not located at MediaWiki:Custom-ModularCSS-render.
==== Step 4: Verifying setup ====
After completing the second step, you may have noticed the following on your wiki's rendering page:
/*Module:ModularCSS:59: No ModularCSS modules were imported!*/
This indicates that the module was successfully installed (although no sub-modules were imported) and the rendering page is functional. However, it does not confirm that step 3 was successful.
To confirm that the whole setup was successful, you can import the MetaVerifyStatus module. To do this, add .import "Dev:ModularCSS/MetaVerifyStatus" on a new line at the end of your wiki's local Module:ModularCSS page. The module page should now look like:
return (require "Dev:ModularCSS")
 .import "Dev:ModularCSS/MetaVerifyStatus"
You can now go to the Special:ModularCSS page to verify the status of ModularCSS rendering at any time. To get the latest rendering status, you will need to clear your browser's cache. The cache should be cleared and the status page should be checked after every ModularCSS configuration change.
If Special:ModularCSS still shows an error (saying there's "no such special page"after clearing your browser's cache, check MediaWiki:Custom-ModularCSS-render for a rendering error message. You may be able to use this error message to troubleshoot.
=== Adding Modules ===
:Modules available for import are listed in "Available Modules".
To add sub-modules, simply append an .import statement (or .importlax to use the less restrictive configuration page) followed by the path to the module on your Module:ModularCSS page. The path of modules hosted globally here on the dev wiki are prefixed with "Dev:", while modules hosted on your local wiki can be imported with the "Module:" prefix.
Example:
return (require "Dev:ModularCSS")
 .import "Dev:ModularCSS/MetaVerifyStatus"
 .importlax "Dev:ModularCSS/HideSpoilerTitle"
Each module imported has an associated configuration page used to modify the generated CSS. Refer to the individual module's documentation for configuration page details and format. Using .importlax instead of .import will use that module's non-MediaWiki configuration page, which allows content moderators to edit the module's CSS configuration.
== Developing Modules ==
Modules will need to return a table consisting of 2-3 key-value pairs:
;page
:(string) The full page name of the default configuration page. The suggested format of configuration page's name is MediaWiki:Custom-ModularCSS-descriptor-thing (for sysop-only access), or Project:Descriptor thing (for non-sysop access, e.g. content moderators). Special:BlankPage may be utilized instead, should the module not require configuration.
;public_page (optional)
:(string) The full page name of the less-restricted configuration page. If this is provided, it is suggested that the page value be of the strict configuration page.
;main
:(function) The function that will take an argument consisting of the parsed bulleted list in a Lua table format. Must return a string of the module's generated CSS.
Note: List items in the configuration page should not be "parent", "self", or "getValue" as they are reserved for table properties/methods. In addition, there cannot be duplicate items on the same level of an item.
=== Parsed list ===
The parsed table passed to the main function represents the hierarchy of the bulleted list. The items are stored with their item name formatted as the key (spaces substituted with underscores) and the value a table of the sub-items. Each item has two properties and one method:
;parent
:(table) The parent item. This value is nil for first level items.
;self
:(string) The raw value of the item. e.g. If the item is "item name", the value stored in self is "item name" (and the key of the item is "item_name").
;getValue (method)
:(string) Gets the value of the item's "first" child. Equivalent to next(item).self.This method should be used for 1 to 1 key-value configuration pairs.
==== Example ====
Source List:
* First Item
** Second Item
*** Third Item
* Fourth Item
local pseudo_parsed = {
 ["First_Item"] = {
 ["Second_Item"] = {
 ["Third_Item"] = {}
 }
 },
 ["Fourth_Item"] = {}
}
print(
 parsed.First_Item:getValue(), --> Second Item
 parsed.Fourth_Item.self, --> Fourth Item
 parsed.First_Item.Second_Item.parent, --> 
)
for key in pairs(parsed) do
 print(key)
end
--[=[ for loop output
First_Item
Fourth_Item
--]=]
== Available Modules ==
:See "Adding Modules" for details on how to import.
The following are list of all modules hosted on the dev wiki available for import. Stable modules will not error if the configuration page is improperly formatted.
Notice: Although the base module is stable, individual modules are of varying stability. An error thrown in an individual module will prevent the entire ModularCSS stylesheet from rendering. Exercise caution while importing experimental ModularCSS modules and check ModularCSS status after every configuration change (see "Verifying setup" for more details).
Module 	Description 	Development Status
/HideSpoilerTitle	Hides the titles of pages deemed to be spoilers. Configuration page details and formatting is subject to change. 	Experimental Beta
/HideSpoilerTitle	Configuration page: Project:Spoiler titles (subject to change) 	Experimental Beta
/MetaVerifyStatus	States the successful rendering status of the whole ModularCSS configuration. If an error appears, even after clearing your browser's cache, an error has likely occurred in one of the sub-modules.	Stable
/UserLinks 	Creates styled user links for message wall and forum threads. 	Broken af
/UserLinks 	Configuration page: TBD 	Broken af
== Troubleshooting ==
=== Importing errors ===
;No ModularCSS modules were imported!
:No sub-modules were imported on the Module:ModularCSS page, and thus the module cannot render any CSS. To add sub-modules see "Adding Modules".
;Invalid module request! Not a string.
:Your .import (or .importlax) statement is not formatted correctly. See "Adding Modules" for details on proper imports.
;Non-existent module requested: <MODULENAME>
:The module you have attempted to import is invalid, or otherwise does not exist. This may be because you're using the wrong prefix (e.g. "Module: where you should use Dev:, or vice versa), you misspelled the module's name, or the module was moved or deleted.
=== Configuration errors ===
Configuration errors not listed here may be listed in that specific sub-module's documentation page. You may likely find that module's doc page in "Available Modules".
;The config page "<CONFIGURATION PAGE>" does not exist on this wiki.
:The configuration page for one or more modules has not yet been created on your local wiki. This may be because you forgot to create the configuration page at "CONFIGURATION PAGE", or you accidentally used the wrong import statement (e.g. using .importlax instead of .import) and have configured the wrong config page.
;Duplicate value in the same bullet level!
:You have created a duplicated value underneath an item on a configuration page. For example, the following is invalid (two "Color" items):
* ConfigItem
** Color
*** #ff0000
** Color
*** #00ff00