Source code is host on github.
Looking for help with your own site rather than to contribute? See getting help.
Use the github issue tracker to signal an issue.
This project is open source, and as such, the maintainers give their free time to build and maintain the source code held within. They make the code freely available in the hope that it will be of use to other developers. It would be extremely unfair for them to suffer abuse or anger for their hard work.
Contributions are welcome.
Please, send your contribution via a github pull request on Pushword/Pushword.
The code is mainly organised in a mono-repo, learn more about the code architecture
See Code Architecture > Development environment
The docs is inside the main repo, you will find write in markdown in packages/docs/content.
On each push to main, a github action compiles the docs and publishes it on pushword.piedweb.com. Nothing to run by hand: what fails the build (a page that does not render) fails the action, and nothing is published.
When requesting or submitting new features, first consider to create a dedicated extension.
If your extension reply to an important community need, you can create a pull request to merge it in this Mono Repo. It will permit to maintain easily it compatibility in next Pushword update. Moreover, extension will be tested at each commit on one of Pushword’s package.
Else, consider create it own git repo and create a Pull Request on the doc to add a link to this fresh extension. The link will be accepted if your extension is well tested and fully functionnal.
This project respect PSR-12 Coding standard. Before your pull-request, run php-cs-fixer and phpstan.
composer rector
composer stan
composer test
The suite runs against SQLite by default. The two server-backed variants are:
composer test-mariadb
composer test-postgresql
This requires a one-time setup of a pushword user owning a pushword_test* database prefix (each parallel worker gets its own pushword_test_w<n> database):
CREATE USER 'pushword'@'%' IDENTIFIED BY 'pushword';
GRANT ALL PRIVILEGES ON `pushword\_test%`.* TO 'pushword'@'%';
The DSN lives in the test-mariadb script (composer.json); override it by exporting PUSHWORD_TEST_DATABASE_BASE_URL before running composer test. The PostgreSQL role must be allowed to create databases because each ParaTest worker gets its own:
CREATE ROLE pushword LOGIN PASSWORD 'pushword' CREATEDB;
With MariaDB and PostgreSQL listening on the test URLs above, compare the three database engines over 100, 1,000 and 10,000 pages:
composer bench-databases
See the benchmark methodology and reference results for a dated SQLite, MariaDB and PostgreSQL comparison.
The benchmark first reports write time plus indexed slug lookups, JSON tag filtering, numeric JSON filtering and a sorted list. A second table uses deterministic synthetic fixtures for two application workloads:
It then runs three end-to-end Pushword pipelines over 100 and 1,000 synthetic pages:
pw:page-scan --skip-external over an internal-link graph;pw:static --workers=1, including HTML rendering and filesystem writes;Pipeline results include duration, throughput, SQL query count and peak memory. Keep the default pipeline ladder short for routine comparisons; opt into 10,000 pages when the longer render-and-scan pass is useful:
PUSHWORD_BENCH_PIPELINE_VOLUMES=100,1000,10000 composer bench-databases
No production content or configuration is used. Change the volume ladder or DSNs when needed:
PUSHWORD_BENCH_VOLUMES=1000,10000,50000 \
PUSHWORD_BENCH_MYSQL_URL='mysql://…/pushword_bench?serverVersion=11.8.6-MariaDB' \
PUSHWORD_BENCH_POSTGRESQL_URL='postgresql://…/pushword_bench?serverVersion=17' \
composer bench-databases
composer test-coverage
Writes coverage/index.html and coverage.xml. It needs the pcov extension (dnf install php-pecl-pcov, apt install php-pcov, …); pcov ships disabled, but the script enables it per run, so no php.ini change is required. Like CI, it runs the suite in three batches — parallel, serial, worker — and merges their reports, so a batch left out never silently reads as uncovered.
This attention would be nice:
Happy coding!