Skip to content

gesinn-it/mediawiki-extensions-PageForms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6,080 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Page Forms

CI Codecov

Note

Fork of the MediaWiki extension PageForms, aimed at simplifying contributions by hosting on GitHub instead of Gerrit, improving quality through better test coverage and continuous integration. From time to time, changes in the upstream repository may be cherry-picked and integrated.

Page Forms, previously known as Semantic Forms, is a MediaWiki extension aimed at simplifying data management through forms. In essence, Page Forms allows users to create, edit, and query data on a wiki without the need for coding. The central feature of Page Forms is the form definition pages, located in the 'Form:' namespace. These pages utilize markup code to define forms, empowering users to create and modify forms without requiring programming knowledge. Forms populate predefined templates and page sections, facilitating data storage and querying, especially when used with Semantic MediaWiki.

Documentation

Versioning

We use SemVer for versioning. See the tags in this repository for available versions.

Contributing

We welcome contributions from the community to help make Page Forms better! Whether you’re fixing bugs, adding new features, improving documentation, or anything else, your efforts are valuable.

Click to see detailed Contributing Guidelines

Step 1: Clone the Repository

Fork and clone our repo to your local machine:

git clone https://github.com/username/projectname.git --recursive

Step 2: Ensure test container is running

The docker-compose-ci repository has already been integrated into the Page Forms repository as a Git submodule. It uses "Make" as main entry point and command line interface.

Ensure, you have Make and Docker installed:

make --version
docker --version

Run lint, phpcs and tests:

make ci

Step 3: Start coding

Make sure there is an issue that describes your changes. Create a new branch and start working on your changes. In issue-1234 replace 1234 with your issue number:

git checkout -b issue-1234

Coding Conventions — General

All source files regardless of language must follow these baseline rules. They are enforced by make ci (lint + phpcs + eslint).

  • Encoding: UTF-8 without BOM

  • Line endings: Unix-style LF (not CR+LF)

  • Indentation: tabs, not spaces

  • Maximum line length: 120 characters

  • No trailing whitespace

  • Newline at end of file

Coding Conventions — PHP

Tooling: mediawiki-codesniffer via PHPCS. Run locally: make composer-phpcs (or make ci).

File structure

  • Every file starts with declare( strict_types=1 );

  • No closing ?> tag

  • One class per file; filename matches class name (UpperCamelCase, e.g. MyClass.php)

  • New code belongs in src/ following PSR-4; includes/ is legacy and should be migrated incrementally

Namespaces and autoloading

  • PSR-4 via Composer (autoload.psr-4 in composer.json)

  • Top-level namespace = extension name (e.g. MediaWiki\Extension\FooBar...)

  • Acronyms treated as single words: HtmlId, not HTMLId

Naming

Element Convention Example

Classes, interfaces, traits

UpperCamelCase

PageFormParser

Methods, variables

lowerCamelCase

getFormContent()

Constants

UPPER_CASE

MAX_FORM_SIZE

Global variables

$wg prefix

$wgPageFormsSettings

Type system

  • Use native type declarations on all parameters, properties, and return types

  • PHPDoc only when native types are insufficient (e.g. string[], array<string, Foo>)

  • Nullable parameters: ?Type, not Type $x = null

  • Prefer ?? (null coalescing) and ??= over ternary isset checks

  • Use arrow functions fn( $x ) ⇒ $x * 2 for single-expression closures

Modern PHP features (target: PHP 8.1+)

  • Constructor property promotion

  • readonly properties for immutable value objects

  • enum instead of class constant groups

  • match() instead of switch when returning a value

Code style

  • 1TBS brace style — opening brace on same line, else/elseif on closing brace line

  • Always use braces, even for single-line blocks

  • Spaces inside parentheses: getFoo( $bar ), empty: getBar()

  • Spaces around binary operators: $a = $b + $c

  • Single quotes preferred; double quotes for string interpolation

  • === strict equality; == only when type coercion is intentional

  • No Yoda conditions: $a === 'foo', not 'foo' === $a

  • elseif not else if

  • true, false, null always lowercase

Architecture

  • private by default; protected only when subclass access is needed

  • Dependency injection over direct instantiation — delegate new Foo() to factories

  • Single Responsibility: one class, one concern

  • No superglobals ($_GET, $_POST) — use WebRequest via RequestContext

  • No new global functions — use static utility classes (Html, IP) if needed

  • Order class members: publicprotectedprivate

Coding Conventions — JavaScript

Tooling: ESLint with eslint-config-wikimedia. Run locally: npm run lint:js (or make ci).

ESLint configuration

Every repository must have a .eslintrc.json at root with "root": true:

{
  "root": true,
  "extends": [
    "wikimedia/client/es2016",
    "wikimedia/jquery",
    "wikimedia/mediawiki"
  ],
  "env": { "commonjs": true }
}

Module system

  • CommonJS modules: require() for imports, module.exports for exports

  • Register modules with ResourceLoader; bundle name pattern: ext.myExtension

  • JS class files match the class name exactly (TitleWidget.js for TitleWidget)

Naming

  • Variables and methods: lowerCamelCase

  • Constructors / classes: UpperCamelCase

  • jQuery objects: $-prefix ($button, not button)

  • Constants: ALL_CAPS

  • Acronyms as single words: getHtmlApiSource, not getHTMLAPISource

Code style

  • Tabs for indentation; single quotes for string literals

  • === and !==; no Yoda conditions

  • Spaces inside parentheses: if ( foo ), getFoo( bar )

  • const and let — never var in new code

  • Arrow functions for callbacks

jQuery

  • Prefer ES6/DOM equivalents over deprecated jQuery methods (.eachforEach, etc.)

  • Never search the full DOM with $( '#id' ) or $( '.selector' ); use hook-provided $content and call .find() on it

  • Prefer $( '<div>' ).text( value ) over $( '<div>text</div>' ) to avoid XSS

MediaWiki APIs

  • Access configuration via mw.config.get( 'wgFoo' ), never direct globals

  • Expose public API via module.exports or within the mw namespace (e.g. mw.echo.Foo)

  • Use mw.storage / mw.storage.session for localStorage/sessionStorage

  • Storage keys: mw-prefix + camelCase/hyphens (e.g. mwedit-state-foo)

Coding Conventions — CSS / LESS

Tooling: stylelint via npm run lint:styles (or make ci). ResourceLoader natively compiles .less files; prefer LESS over plain CSS.

Naming

  • Classes and IDs: all-lowercase, hyphen-separated

  • Use an extension-specific prefix to avoid conflicts (e.g. pf-, smw-, mw-)

  • LESS mixin names: mixin- prefix + hyphen-case (e.g. mixin-screen-reader-text)

Whitespace and formatting

  • One selector per line, one property per line

  • Opening brace on the same line as the last selector

  • Tab indentation for properties and nested rules

  • Semicolon after every declaration, including the last

  • Empty line between rule sets

Colors

  • Lowercase hex shorthand preferred: #fff, #252525

  • rgba() when alpha transparency is needed; transparent keyword otherwise

  • No named color keywords (except transparent), no rgb(), hsl(), hsla()

  • Ensure color contrast meets WCAG 2.0 AA

LESS specifics

  • CSS custom properties (design tokens) preferred over LESS variables for new code

  • @import only for mixins and variables (variables.less, mixins.less); do not use @import for bundling conceptually related files

  • Omit .less extension in @import statements

  • Bundle related files via the styles array in skin.json / extension.json

Anti-patterns to avoid

  • !important — avoid except when overriding upstream code that also uses it

  • z-index — use natural DOM stacking order where possible; document exceptions

  • Inline style attributes — always use stylesheet classes instead

  • float / text-align: left hardcoded — use /* @noflip */ annotation when needed, otherwise ResourceLoader’s CSSJanus handles RTL automatically


Step 4: Test your changes

Before making any code changes to fix a bug or implement a feature:

  1. Check whether an existing test already covers the described behavior.

  2. If not, write or adapt a test that reproduces the issue — it must fail first.

  3. Only after a failing test exists, make the code changes.

  4. Re-run the test to confirm it passes (green).

Test-first approach

All tests run inside a containerized MediaWiki environment managed via docker-compose-ci (the build/ submodule). Never run tests directly against a local PHP or Node.js installation.

Always run make install before executing tests to ensure that the latest file changes are copied into the container. Changes to source or test files on the host are not automatically reflected in a running container.

make install

PHPUnit tests

Run all PHPUnit tests:

make install composer-phpunit

Run a single test class or method (filtered):

make install composer-phpunit COMPOSER_PARAMS="-- --filter YourTestName"

Run a specific test suite:

make install composer-phpunit COMPOSER_PARAMS="-- --testsuite your-suite-name"

For interactive use, bash into the running container:

make bash
> composer phpunit -- --filter YourTestName

Node QUnit tests

Run all JavaScript tests:

make install npm-test

There is no direct make target for filtering individual tests. Bash into the running container to run a specific test file or test case:

make bash
> npm run node-qunit -- tests/node-qunit/yourtest.test.js

Filter by test description:

make bash
> npx qunit --require ./tests/node-qunit/setup.js 'tests/node-qunit/**/*.test.js' --filter "your test description"

Pre-commit validation gate

Before every commit, run the full CI suite to confirm nothing is broken:

make ci

Step 5: Commit your changes

Commit messages follow the Conventional Commits specification.

Commit format:

type(scope): short description

The scope is optional and should describe the affected subsystem, module, or dependency when useful.

Examples:

  • feat(api): add autocomplete endpoint

  • fix(parser): handle empty token lists

  • docs(readme): explain input architecture

  • refactor(parser): simplify token parsing

  • deps(smw): bump from 5.1.0 to 5.2.0

  • ci(github): update workflow configuration

  • test(api): add autocomplete tests

Recommended commit types:

  • feat — new functionality

  • fix — bug fixes

  • deps — dependency updates

  • docs — documentation changes

  • refactor — internal code changes without behavioral change

  • test — tests added or updated

  • ci — changes to continuous integration configuration

  • chore — repository maintenance tasks without impact on runtime behavior

Dependency updates:

  • Use the deps type for dependency upgrades

  • The scope should identify the dependency being updated

  • Include the version change when applicable

Example:

  • deps(smw): bump from 5.1.0 to 5.2.0

Guidelines:

  • Use the imperative mood (e.g. "add feature", not "added feature")

  • Keep the subject line concise

  • Use the commit body to explain why, not only what

  • Scopes should be short, lowercase identifiers (e.g. api, parser, smw, mediawiki, docker)

  • Use chore only for repository maintenance tasks that do not affect runtime behavior, dependencies, CI configuration, or tests

git commit -m "Description of your changes"

Step 6: Push!

Push your branch and open a pull request.

git push origin feature/your-feature-name

Local testing notes

PHP integration tests (PHPUnit/JSONScript)

For focused test runs (for example autocomplete-related API tests), use:

make install composer-phpunit COMPOSER_PARAMS="-- --filter=autocomplete"

After the first run, you can use this faster variant for repeated runs:

make composer-phpunit COMPOSER_PARAMS="-- --filter=autocomplete"

JavaScript tests (Node QUnit)

Run the default JS test pipeline (ESLint + i18n + Node QUnit):

make npm-test

Run only Node QUnit tests (faster feedback loop):

docker compose -f build/docker-compose.yml --project-name pageforms-mysql --profile mysql exec -T wiki bash -lc "cd /var/www/html/extensions/PageForms && ./node_modules/.bin/qunit --require ./tests/node-qunit/setup.js 'tests/node-qunit/**/*.test.js'"

Run one specific JS test file:

docker compose -f build/docker-compose.yml --project-name pageforms-mysql --profile mysql exec -T wiki bash -lc "cd /var/www/html/extensions/PageForms && ./node_modules/.bin/qunit --require ./tests/node-qunit/setup.js tests/node-qunit/simpleupload.test.js"

New or renamed test files are copied into the Docker image at build time. After changing test files, run commands via make install …​ at least once, then you can use make composer-phpunit …​, make npm-test, or direct qunit runs in the container for repeated runs.


This extension is part of semantic::core - Enterprise Class MediaWiki distribution.

.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors