Southclaws / storyden

With a fresh new take on traditional bulletin board forum software, Storyden is a modern, secure and extensible platform for building communities.
https://www.storyden.org/
Mozilla Public License 2.0
93 stars 11 forks source link

Frontend theming #252

Open Southclaws opened 1 month ago

Southclaws commented 1 month ago

While Storyden is architected completely differently to all other forum software, by being API-first and with a decoupled frontend implementation (a "reference implementation" so to speak) the provided frontend is still intended as a production grade client for Storyden, just not the only possible frontend. At this point, Storyden has been used to build three other platforms with fully custom frontends which helped prove its versatility as a social platform foundation.

With that said, customising the official frontend implementation is a must as obviously not every user will want to spend time and resources implementing a custom frontend from scratch just to provide a brand-equivalent or white-labelled experience.

One of the nice things with PHP forums and platforms like WordPress is it's incredibly easy to theme them as the output from the backend is just a HTML tree that follows a roughly standard structure along with whatever plugins inject (which also provide their own styles.) And this results in a really nice ecosystem of drop-in themes which are, at the most basic level (ignoring plugins) just stylesheets and maybe some JS.

Unfortunately, Storyden cannot go that route because the frontend is a React application, so the backend cannot (easily) simply inject HTML or other resources without some abstraction layer in between that's also secure and versatile.

But it's not impossible, I do have concepts of a plan and it'll likely boil down to plain old CSS and a bit of discipline when it comes to writing frontend screens and components.

Styling proposal

The frontend follows a fairly common structure of screens and components. Screens roughly map to pages and/or modals and components are the elements within (and shared between) those screens.

Let's look at the ThreadScreen component as an example, a simplified overview of the structure:

<LStack>
  <styled.form>
    <HStack>
      <Breadcrumbs />
      <HStack>
        <ThreadMenu />
      </HStack>
    </HStack>
    <Byline />
    <Heading />
    <ThreadBodyInput />
  </styled.form>
  <ThreadReplyStatus />
  <ReplyList />
  <ReplyBox />
</LStack>

This can easily be annotated at the top level with class names (illustrative, obviously non-structural components themselves will declare their own class names and likely be namespaced logically)

<LStack className="thread-screen__container">
  <styled.form className="thread-screen__edit-form">
    <HStack className="thread-screen__header">
      <Breadcrumbs className="thread-screen__breadcrumbs" />
      <HStack className="thread-screen__controls">
        <ThreadMenu className="thread-screen__thread-menu" />
      </HStack>
    </HStack>
    <Byline className="thread-screen__byline" />
    <Heading className="thread-screen__title" />
    <ThreadBodyInput className="thread-screen__body" />
  </styled.form>
  <ThreadReplyStatus className="thread-screen__reply-status" />
  <ReplyList className="thread-screen__reply-list" />
  <ReplyBox className="thread-screen__reply-box" />
</LStack>

Then, one or many stylesheets can be edited/stored/provided by the backend and injected into the frontend root layout server-side render similar to how theme.css already is for the accent colour. Then the stylesheet can live in a top-most @layer which ensures it can override all the defaults from Panda's generated CSS.

The hard part (which is not unique to this situation, but will require some extra care while modifying components) is to ensure:

  1. names stay consistent
  2. names don't change too much/too often
  3. necessary changes to structure are done in such a way that can keep themes happy and not break as often

Now it's been quite a while since I worked with platforms that handle direct CSS, especially with React, so there might be better ways to do this and more modern naming conventions than BEM that could make more sense for this use-case.

It'll also take a significant amount of time to actually implement this site-wide and would also require building an actual separate custom theme to validate it works as well as provide an ongoing testing environment for future frontend changes.

I'd like to get your thoughts @adrfranklin as you've worked a lot more with oldschool forums and themeable PHP apps before!