Revision indexing in progress... (search in this revision will be accurate after indexed)
Enable CI/CD by adding .onedev-buildspec.yml
| src | Loading last commit info... | |
| tests | ||
| .gitignore | ||
| README.md | ||
| composer.json | ||
| phpunit.xml |
README.md
qalam — قلم
Content wrappers for the Islamic Network ilm CMS: the shared layer between Directus and the public Kipchak APIs (pray, events, people). Included as a Composer package by the APIs and the Islamic Network SDK.
Everything the API contracts promise that Directus doesn't do lives here:
| Component | Job |
|---|---|
Markdown\Renderer | CMS Markdown → HTML (CommonMark; inline HTML allowed, unsafe links not) |
Markdown\BracketSpans | The authoring convention […]{.translit} / […]{lang=ur} → spans |
Html\LanguageNormalizer | Wraps untagged Arabic runs in <span lang="ar">; promotes all-Arabic blocks to <p lang="ar" dir="rtl">; honorific ligatures (ﷺ) flow inline |
Text\Prose | A prose field as served: {raw: <markdown>, html: <rendered+normalized>} |
Directus\Translations | Pivots *_translations rows into {ar, ar-Latn, en, …} objects (BCP 47 keys, canonical order, empties omitted) |
Text\DiacriticFolder | Search folding: tasbih matches Ṣalāt al-Tasbīḥ and تَسْبِيح |
Content\Times | The times-of-day contract enum → {key, label} pairs |
Api\Pagination | ?page/?limit parsing + the meta block ({total, page, limit, pages}) |
The response envelope ({code, status, data}) is not here — Kipchak owns it.
Requirements
PHP 8.4+ (uses the new Dom\HTMLDocument API), ext-dom, ext-intl,
ext-mbstring.
Tests are the contract
tests/fixtures/ holds copies of the locked API samples from ../api/.
The pipeline tests assert that rendering each sample's raw produces its
html byte-for-byte (modulo inter-tag whitespace) — if a convention changes,
change the sample first and the tests say what code must follow.
composer install
composer test
Usage sketch
use IslamicNetwork\Qalam\Directus\Translations;
use IslamicNetwork\Qalam\Text\Prose;
use IslamicNetwork\Qalam\Content\Times;
$t = new Translations($directusRow['translations']);
$record = [
'name' => $t->text('name'), // {ar, ar-Latn, en}
'description' => $t->prose('description'), // {en: {raw, html}}
'translations' => $t->text('translation'), // {ar-Latn, en, ur, …}
'times' => Times::toApi($junction['times']),
];