Skip to content
View in the app

A better way to browse. Learn more.

ernestdefoe.online

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
ernestdefoe.online

Extensions, themes & support for Flarum and Invision Community

Vibe coding for the community web. Report a bug, request a feature, or dig into the source — this is where the tools you use get built, in the open.

We do custom Bespoke Invision Community apps. If you have an idea for something you want then use the contact form to get in touch with us.
Knowledge base

Things that cost me a day, so they cost you none

Working notes from building Invision Community and Flarum applications. Mostly the failures that give no error at all — the ones where everything installs cleanly and quietly does the wrong thing.

92 articles

Invision Community 5

86 articles

Extensions and contracts

39

What each extension point is for, what it must declare, and what happens when it is wrong — which is usually nothing visible.

Languages and text

5

The string table, translation, and the places where text does not appear where you expected it to.

Theming, templates and forms

9

Theme hooks, CSS that survives both colour schemes, and building forms that do not throw on render.

Background work and scheduled tasks

5

The queue system, work that has to happen after the response, and jobs that finish without doing anything.

Data, settings and storage

11

The database layer, settings, tags, file storage, and backing up a live site.

AI features and expectations

5

What these features do, what they cost, and what buyers reasonably but wrongly assume they do.

Application structure and releases

11

The JSON files an application is made of, versioning and upgrade steps, and testing from the command line.

Realtime, chat and calls

1

WebSocket gateways, relays and the server-side pieces live features depend on — where "it works when I test it" and "it works for your members" are different claims.

Nothing matches that.

Theming, templates and forms

Theme hooks, CSS that survives both colour schemes, and building forms that do not throw on render.

9 Articles in this category

  1. Ernest Defoe ·
    A class name that no longer exists is not an error. It applies no styling, logs nothing, and breaks no build. The element simply renders unstyled, and because the surrounding markup is right, it is easy to look straight past. This is how a panel shipped with its text flush against the left edge of its own box. The markup asked for ipsPad, which is an Invision Community 4 class. In 5 it does not exist, so there was no padding at all — and nothing anywhere said so. Check before you trust a cla
    • 0 comments
    • 31 views
  2. Ernest Defoe ·
    You want to change what a theme outputs at a specific point. The obvious approach is a custom template hook with type replace. Install the application and the log says: Data truncated for column 'template_hookpoint_type' at row 1 The application installs, the hook does not, and nothing on the front end changes. The four types The column is an enum: template_hookpoint_type enum('before','inside-start','inside-end','after') That is the whole list. The string 'replace' does appear in core's o
    • 0 comments
    • 24 views
  3. Ernest Defoe ·
    You add a field to an AdminCP form, load the page, and get this: [[Template core/global/forms/checkboxset is throwing an error. This theme may be out of date. Run the support tool in the AdminCP to restore the default theme.]] The theme is fine. Restoring it will not help. The message is what Invision Community prints when a template throws, and the template threw because of the options you passed to the field — but the message names the template, so it sends you to the support tool and the
    • 0 comments
    • 47 views
  4. Ernest Defoe ·
    Invision Community 5 renders in a light or a dark scheme. Custom CSS written while looking at one of them usually breaks in the other, and the way it breaks is quiet: nothing errors, nothing logs, and the developer's own screen looks correct. How the two schemes work Core declares its palette twice: light values at :root, then overrides under [data-ips-scheme="dark"]. The attribute is written onto <html> from front/global/htmlDataAttributes.phtml and can be light, dark, or system. When
    • 0 comments
    • 39 views
  5. Ernest Defoe ·
    Container queries let a block lay itself out based on the space it was given rather than the size of the browser window — the only way to make one block correct in both a narrow sidebar and a wide content column. A media query cannot tell those apart, because the viewport is the same width in both. The trap An element that declares container-type cannot be styled by queries against that container. Only its descendants can. /* BROKEN: the grid rule never applies */ .block { container-type:
    • 0 comments
    • 25 views
  6. Ernest Defoe ·
    A form containing an editor throws the moment the page is opened, not on submit, if its app and key do not name a real extension. The symptom OutOfBoundsException: Admin #0 /applications/myapp/modules/admin/.../controller.php(340): IPS\Helpers\Form\Editor->__construct(...) The exception message is the key alone, with no mention of the app, which makes it read like a missing language string. The cause new Editor( 'body', '', TRUE, array( 'app' => 'myapp', 'key' => 'Admin' ) ) This re
    • 0 comments
    • 29 views
  7. Ernest Defoe ·
    An application that registers a core/Loader extension and returns a flat list of URLs will take down every front-end page on the site, not just its own. The symptom Every front page returns a 500. The log says: TypeError: array_merge(): Argument #2 must be of type array, string given #0 /system/Dispatcher/Front.php(188): array_merge(Array, 'https://...') Note where the error comes from: the dispatcher, not your application. Nothing in the trace names the app responsible. The cause The front
    • 0 comments
    • 25 views
  8. Ernest Defoe ·
    Writing custom CSS to a theme in code appears to work. The setter runs, caches clear, save() reports success — and the column is never touched. The cause ActiveRecord::save() writes only fields recorded as changed: $data = $this->_new ? $this->_data : $this->changed; But Theme::set_custom_css() assigns straight into _data and never marks the field: public function set_custom_css( string $value ) : void { $value = str_replace( '</style>', '', $value ); $this->_data['
    • 0 comments
    • 27 views
  9. Ernest Defoe ·
    Every widget needs TWO language keys block_<key> and block_<key>_desc. Without them the AdminCP block picker lists raw key strings. Easy to ship without noticing, because the block itself renders fine. Use ipsWidget markup, never your own ipsBox The widget framework already supplies the box. Emitting ipsBox yourself nests a box inside a box and the header stops matching every other block on the page. <div class="ipsWidget ipsWidget--vertical"> <h3 class="ipsWidget__h
    • 0 comments
    • 26 views

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.