tryhackx/flarum-advanced-pages
Composer 安装命令:
composer require tryhackx/flarum-advanced-pages
包简介
Create advanced custom pages with HTML, BBCode, Markdown, PHP, or plain text, featuring nested hierarchies, breadcrumbs, and granular console-managed permissions for Flarum 2.x.
关键字:
README 文档
README
Create advanced custom pages with HTML, BBCode, Markdown, PHP,
or plain text content types for your Flarum 2.x forum. A powerful
alternative to fof/pages with multi-format support, live preview,
formatting toolbars, and granular access control.
Latest highlights (2.1.0):
- Nested / child pages with a Parent Page selector, drag-and-drop ordering & nesting in the admin (grab the
⋮⋮handle), parent-chain breadcrumbs, and optional per-tree breadcrumb CSS (style or hide them).- Per-content-type creation permissions — control who can create Plain Text / BBCode / Markdown pages from the admin grid, and who can create the sensitive HTML / PHP pages via a dedicated console command (
php flarum advancedpages:permission).- Per-page "Allow script execution" toggle —
<script>tags in a page now run only when you explicitly opt in (off by default).- Cross-database visibility — per-group visibility now works on SQLite and PostgreSQL too, not just MySQL/MariaDB.
$actornow works inside PHP pages.
Note: Advanced Pages targets the 2.x line only (Flarum 2.x).
Features
- 6 content types — HTML (rendered raw — admin/permission-gated), BBCode, Markdown, PHP (server-side, admin/permission-gated), Plain Text, and Redirection (forward to another URL — great for pinned menu links).
- View counter — every page tracks how many times it's been viewed,
shown in the admin list and readable from PHP pages (
$page->view_count). - Nested pages — parent/child hierarchy with slash-based URLs and breadcrumbs.
- Pinned navigation — pin any page into the forum's sidebar navigation menu (alongside All Discussions, Members, Badges…) with an optional FontAwesome icon; pinned links follow the page-list order and respect each page's visibility.
- Formatting toolbars — context-aware buttons for the BBCode and Markdown editors.
- Live preview — Raw / Preview toggle with syntax highlighting (highlight.js One Dark).
- Code editor — CodeMirror-powered editor for HTML and PHP with syntax highlighting.
- Code blocks — rendered code gets Select / Copy buttons and a capped, scrollable height; the toolbar can optionally be added to regular forum posts too (admin setting).
- BBCode extensions —
[table],[spoiler],[center], extended[url]parser (configurable). - Newline modes — Flarum vanilla or preserve-all for BBCode pages.
- Spoiler system —
[spoiler]/[spoiler=Title]with permission-based visibility (advancedPages.viewSpoilers, default Members). - Admin panel — full CRUD with pagination, per-page selector,
inline settings, Save Changes + Reset Settings buttons (Reset
opens Flarum core's
ResetExtensionSettingsModalpopulated with this extension's settings). - SEO support — meta descriptions and proper
<title>tags. - Access control — publish, hide (admin-only), restrict (login-required), per-group visibility (works on MySQL/MariaDB, SQLite 3.38+ and PostgreSQL).
- Granular permissions — manage pages, view spoiler content, and per-content-type page creation (text/BBCode/Markdown in the admin grid; HTML/PHP via console command).
- Clean URLs — pages live at
/p/{slug}, including nested paths like/p/docs/getting-started.
Screenshots
Mobile view — discussion list rendered with different combinations of TryHackX extensions (thumbnails + ratings + views, thumbnails + views, thumbnails only, ratings only, views only, vanilla Flarum).
Advanced Pages admin panel — page management, BBCode tag toggles ([table], [spoiler], [center], extended [url]), forum spoiler replacement and the Save Changes / Reset Settings row, plus the Manage Advanced Pages and View spoiler content permissions.
Desktop discussion list with the full TryHackX stack — thumbnail sliders on the left, star ratings on the right, magnet button next to each topic.
Desktop discussion list — hover state showing the magnet tooltip loading inline (powered by tryhackx/flarum-magnet-link).
Support Development
If you find this extension useful, consider supporting its development:
- Monero (XMR):
45hvee4Jv7qeAm6SrBzXb9YVjb8DkHtFtFh7qkDMxS9zYX3NRi1dV27MtSdVC5X8T1YVoiG8XFiJkh4p9UncqWGxHi4tiwk - Bitcoin (BTC):
bc1qncavcek4kknpvykedxas8kxash9kdng990qed2 - Ethereum (ETH):
0xa3d38d5Cf202598dd782C611e9F43f342C967cF5
You can also find the donation option in the extension's admin settings panel.
Requirements
- Flarum
^2.0 - PHP
^8.2 - PHP memory_limit
256Mminimum (512M+ recommended — see Memory below).
Installation
composer require tryhackx/flarum-advanced-pages php flarum migrate php flarum cache:clear
Updating
composer update tryhackx/flarum-advanced-pages php flarum migrate php flarum cache:clear
Usage
Creating pages
- Go to Admin Panel → Advanced Pages.
- Click Create Page.
- Choose a content type and write your content.
- Configure visibility (published, hidden, restricted, group access).
- Save — the page is available at
/p/{your-slug}.
Content types
| Type | Description | Security |
|---|---|---|
| HTML | Full HTML with styles / forms / (opt-in) scripts | Rendered raw, NOT sanitised. Creation gated by advancedPages.create.html (console-only). <script> runs only if Allow script execution is enabled per page. |
| BBCode | BBCode with custom tags & toolbar | Escaped and parsed via s9e/TextFormatter |
| Markdown | Full Markdown with live preview | Escaped and parsed via s9e/TextFormatter |
| PHP | Server-side PHP execution (eval) |
Full server privileges — not a real sandbox. Creation gated by advancedPages.create.php (console-only). Errors logged, never shown. |
| Plain Text | Auto-escaped text with URL linking | Fully escaped output |
| Redirection | Forwards visitors to another URL | Target must be an https:///http:// address or a root-relative /path — validated on save, so no javascript:/data: schemes. Creation gated by advancedPages.create.redirect (admin grid). |
BBCode toggles
| Setting | Tags | Default |
|---|---|---|
| Tables | [table] [tr] [th] [td] |
On |
| Spoiler | [spoiler] [spoiler=Title] |
On |
| Center | [center] |
On |
| Extended URL | [url] (accepts URLs Flarum rejects) |
Off |
| Replace Forum Spoiler | swap Flarum's default [spoiler] for the Advanced Pages details/summary style across all posts |
Off |
| Code buttons in posts | add the Select / Copy code-block toolbar to regular forum posts (it's always on for Advanced Pages) | Off |
After toggling BBCode settings, clear the formatter cache:
php flarum cache:clear
Newline mode (BBCode)
Per-page newline behaviour:
- Flarum (default) — multiple newlines collapse to a single break (vanilla Flarum behaviour).
- Preserve — every newline is kept as a line break (code blocks keep real newlines, so they still highlight correctly).
PHP pages
⚠️ PHP pages run via
eval()with full server privileges. The closure only scopes the variables below — it is not a security sandbox. Treat the ability to create PHP pages as equivalent to shell access. By default only administrators can create them.
PHP page code runs in a closure with access to:
$page— current Page model$actor— the current user. This is always aUserobject; for guests it is a guest instance ($actor->isGuest() === true), notnull.$settings— FlarumSettingsRepository$csrfToken— the current session's CSRF token (see Forms below)$pages— read-only page-tree helper for nav menus (see Building a nav menu below)- the usual PHP superglobals:
$_GET,$_POST,$_FILES,$_SERVER, …
<h1>Welcome, <?= htmlspecialchars($actor->isGuest() ? 'Guest' : $actor->display_name) ?></h1> <p>Current time: <?= date('Y-m-d H:i:s') ?></p>
PHP errors are written to Flarum's log but never shown to visitors.
Forms, GET, POST and file uploads
PHP pages can read query strings and handle form submissions — including file uploads — through the normal PHP superglobals:
- GET —
…/p/your-page?q=hello→$_GET['q']. Works out of the box. - POST / file upload — a
<form method="post">(useenctype="multipart/form-data"for files) submits back to the same page URL; read$_POST/$_FILES. Because the page lives on a normal forum route, Flarum's CSRF protection applies, so the form must include the session token — emit it with the$csrfTokenvariable:
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST'): ?> <p>You said: <?= htmlspecialchars($_POST['message'] ?? '') ?></p> <?php if (!empty($_FILES['file']['name'])): ?> <p>Uploaded: <?= htmlspecialchars($_FILES['file']['name']) ?> (<?= (int) $_FILES['file']['size'] ?> bytes)</p> <?php endif; ?> <?php endif; ?> <form method="post" enctype="multipart/form-data"> <input type="hidden" name="csrfToken" value="<?= htmlspecialchars($csrfToken) ?>"> <input name="message" placeholder="Say something"> <input type="file" name="file"> <button type="submit">Send</button> </form>
A POST without a valid csrfToken is rejected with HTTP 400 — this is Flarum's
standard CSRF protection, not a limitation of the extension. (A live demo page
ships at /p/php-request-test.)
Building a nav menu — the $pages tree helper
PHP pages get a read-only $pages helper for walking the page tree, so you can
generate a navigation menu, a sidebar, a sitemap, etc. It only ever returns
pages the current viewer is allowed to see (drafts, hidden, restricted and
per-group pages are filtered out automatically) and is ordered to match the
admin tree — so menus never leak hidden pages. The whole visible set is loaded
in a single query, no matter how many calls you make.
| Method | Returns |
|---|---|
$pages->all() |
All visible pages (flat, ordered). |
$pages->roots() |
Top-level pages (no parent). |
$pages->children($slug) |
Direct children of a page (by slug, id or Page). |
$pages->tree($slug) |
Nested ['page' => Page, 'children' => [...]] array — pass a slug (e.g. 'docs') for that subtree, or nothing for the whole forest. |
$pages->find($slug) |
A single page by slug or id (or null). |
$pages->ancestors($page) |
The parent chain (root → immediate parent). |
Each Page exposes ->title, ->slug, ->content_type, ->is_published,
->view_count (the hit counter), etc. — so a PHP page can, for example, build a
"most viewed pages" list with $pages->all()->sortByDesc('view_count').
<?php // A nested <ul> menu of everything under /p/docs (visibility-aware). function ap_menu(array $nodes): void { if (!$nodes) return; echo '<ul>'; foreach ($nodes as $node) { $p = $node['page']; printf('<li><a href="/p/%s">%s</a>', htmlspecialchars($p->slug), htmlspecialchars($p->title)); ap_menu($node['children']); // recurse into children echo '</li>'; } echo '</ul>'; } ap_menu($pages->tree('docs')); ?>
Nested pages, ordering & breadcrumbs
Pages form a tree. The hierarchy (parent + order) is the organisation; the slug is the independent URL. A child page renders breadcrumbs built from its parent chain (each ancestor links to its own page).
Two ways to organise pages:
-
Parent Page selector in the editor — pick a parent (for a brand-new page it also suggests a matching child slug, which you can edit).
-
Drag and drop in the admin list — grab the
⋮⋮handle at the end of a row and:- drop it onto another page to nest it underneath, or
- drop it between rows to reorder it at that level.
Order is saved per parent; a page can't be dropped into its own subtree.
Slugs may be a slash path (e.g. docs/getting-started) or flat — your choice;
they accept lowercase a-z0-9- segments joined by single / (no leading,
trailing or doubled slashes).
Pinning a page to the navigation menu
In the page editor, tick Pin to navigation menu to surface the page as a link in the forum's index sidebar navigation — the same menu that holds All Discussions and links added by other extensions (Members, Badges, …). When pinned, two optional fields appear:
- Menu icon — a FontAwesome class such as
fas fa-bookorfar fa-file-alt(leave it blank for a default icon). - Short Name — a shorter label to show in the menu when the page title is too long for a nav item; leave it blank to use the page title.
Pinned links are ordered exactly like the admin page list (parent/child tree, then per-level order) and honour every visibility rule — a draft, hidden, restricted or group-limited page is only shown in the menu to viewers who are allowed to open it. Nothing is pinned by default.
Redirection pages
A Redirection page (content type Redirection) forwards visitors to another
address — enter an https://… URL or a root-relative /path (e.g. /tags). The
target is validated on save, so it can never carry a javascript: or data:
scheme.
Two behaviours, chosen per page with Redirect immediately:
- On (default) — visiting
/p/{slug}issues a real HTTP 302 redirect straight to the target (no page shown). - Off — the page shows a 5-second countdown (“You will be redirected in N s…”) above the destination link, then forwards automatically. No button to click.
Either way the visit is counted first. Combined with pinning, this is the
easiest way to add a custom menu link — internal or external — to the forum
navigation. The menu link points at the page's own /p/{slug} (not straight at
the destination) precisely so those clicks pass through the view counter before
forwarding.
Tip: to redirect, use this content type — don't write a PHP page that calls
header('Location: …'). PHP pages are rendered inline (their output is captured, not sent as a raw response), soheader()andexit()won't work there.
Per-tree breadcrumb styling
On a root page (Parent Page = none), tick Custom breadcrumbs CSS? to
reveal a small CSS editor. Whatever you write applies to the breadcrumbs of that
page and everything nested under it — target .AdvancedPages-breadcrumbs. For
example, hide them entirely:
.AdvancedPages-breadcrumbs { display: none; }
Page visibility
| Option | Description |
|---|---|
| Published | Accessible to permitted users. |
| Draft | Page exists but is not accessible. |
| Hidden | Only visible to administrators. |
| Restricted | Requires login to view. |
| Group access | Restrict to specific user groups. |
Permissions
Out of the box, only administrators can create, edit or delete pages. To let other groups help, you grant access in two places:
- The admin Permissions page — for everyday things: who can create the safe page types (Plain Text, BBCode, Markdown), who can edit/delete pages, and who can see spoiler content. Just tick the boxes.
- One console command — for the two powerful page types, HTML and PHP.
Why are HTML and PHP separate? An HTML page can run JavaScript in every visitor's browser, and a PHP page runs code on your server. Letting a group create those is a big deal, so it's deliberately kept out of the clickable admin panel (you can't enable it by accident) and done from the server console instead.
What each permission lets a group do:
| Permission | Where you grant it | Lets the group… |
|---|---|---|
| Create: Plain Text / BBCode / Markdown | Admin → Permissions page | Create those (safe, escaped) page types. |
| Create: HTML | Console (below) | Create HTML pages (raw HTML/JS). |
| Create: PHP | Console (below) | Create PHP pages (server-side code). |
| Manage Advanced Pages | Admin → Permissions page | Edit & delete existing pages. |
| View spoiler content | Admin → Permissions page | See [spoiler] content (default: Members). |
Editing also needs Manage Advanced Pages. On top of that, turning a page into — or editing — an HTML/PHP page needs that group's HTML/PHP create permission too, so a manager can't sneak executable code in without it.
The console command
php flarum advancedpages:permission <action> [<group>] [<type>] [--force]
<action>—list,grant, orrevoke.<group>— the group's name (e.g.Members, or"Trusted Authors"in quotes if it has a space) or its number. Runlistto see the numbers.<type>—text,bbcode,markdown,html,php, orall(every create type at once). You can also passmanage(edit/delete) orspoilers.--force— only needed when grantinghtml,phporall. It's a safety confirmation for the dangerous ones (revoking never needs it).
Recipes:
# See who can do what (and the group numbers) php flarum advancedpages:permission list # Let the "Members" group write Markdown pages (same as ticking the box) php flarum advancedpages:permission grant Members markdown # Let a "Trusted Authors" group build HTML pages (dangerous → needs --force) php flarum advancedpages:permission grant "Trusted Authors" html --force # Let a group create PHP pages — by group number this time php flarum advancedpages:permission grant 4 php --force # Let your moderators edit & delete any page php flarum advancedpages:permission grant Mods manage # Take a permission back php flarum advancedpages:permission revoke Members markdown
Changes apply immediately — no cache clear. Administrators always have every permission, so you can't (and don't need to) target them.
Memory requirements
Flarum compiles all extension LESS styles together. If you get
PHP Fatal error: Allowed memory size exhausted:
- Set
memory_limitto at least256Minphp.ini(512M+ recommended). - WAMP users: Apache with
mod_fcgiduses thephp.iniin the Apache bin directory, not the PHP directory. - Restart Apache after changes.
Security
This extension intentionally lets trusted authors publish raw HTML and run server-side PHP — that is the whole point. Understand the model before delegating page creation:
- HTML is rendered raw and is NOT sanitised. Whoever can create HTML pages
can publish arbitrary markup and (if Allow script execution is enabled on
that page) JavaScript to every visitor. There is no HTMLPurifier. Treat
advancedPages.create.htmlas "can run JS in every visitor's browser". - PHP pages run via
eval()with full server privileges — not a sandbox. TreatadvancedPages.create.phpas equivalent to shell access. PHP errors are logged, never shown to visitors. - Safe by default: out of the box only administrators can create or edit
pages. HTML and PHP creation can only be delegated via the
advancedpages:permissionconsole command (never an accidental panel click). - The per-page Allow script execution toggle gates
<script>tags (off by default). It is not a sandbox: HTML is rendered raw, so a page can still run JavaScript by other means (inline event-handler attributes likeonerror,<svg onload>, etc.) regardless of the toggle. Treat anyone allowed to create HTML pages as able to run JS in every visitor's browser, toggle or not — the toggle is a convenience for disabling<script>blocks, not a trust boundary. - The raw
contentfield is exposed only to admins and holders ofadvancedPages.manage(so page managers can edit without blanking it); everyone else gets only the rendered output. - Spoiler content is stripped server-side for users without
advancedPages.viewSpoilers, regardless of the Replace Forum Spoiler setting. - URL-scheme blocking (
javascript:,data:,vbscript:) in the extended[url]BBCode parser.
Database support
Works on every database Flarum 2.x supports — MySQL / MariaDB, SQLite 3.38+, and PostgreSQL — including the per-group page visibility feature (uses Laravel's cross-database JSON query builder).
Note on cache clearing (Windows)
After php flarum cache:clear or enabling/disabling the extension, the very
first page load may briefly return HTTP 500 and succeed on refresh. This is a
known Flarum/Symfony behaviour on Windows (the translation-catalogue cache
is rebuilt and concurrent first requests can collide on the file rename) — it
affects the whole forum, not just this extension, and clears itself once the
cache is warm. Loading any one page once after clearing the cache avoids it.
Links
License
MIT License. See LICENSE for details.
tryhackx/flarum-advanced-pages 适用场景与选型建议
tryhackx/flarum-advanced-pages 是一款 基于 JavaScript 开发的 Composer 扩展包,目前已累计 401 次下载、GitHub Stars 达 2, 最近一次更新时间为 2026 年 04 月 06 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「cms」 「markdown」 「html」 「extension」 「breadcrumbs」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 tryhackx/flarum-advanced-pages 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 tryhackx/flarum-advanced-pages 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 tryhackx/flarum-advanced-pages 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Texy converts plain text in easy to read Texy syntax into structurally valid (X)HTML. It supports adding of images, links, nested lists, tables and has full support for CSS. Texy supports hyphenation of long words (which reflects language rules), clickable emails and URL (emails are obfuscated again
GraphQL authentication for your headless Craft CMS applications.
Set Links with a specific language parameter
Supercharged text field validation.
Adds more BBCode
Integrate with Snipcart.
统计信息
- 总下载量: 401
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 30
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-06



