New site themes available to try

I think I got mobile support working. At least, it works when using ?mobile_view=1 now.

Also, I figured out how to theme the scrollbar(s) and timeline slider… which I just now noticed also affects the editor, so the scrollbar there now fits the theme too.



… and the post editor:

2 Thanks

Nice!! How much tweaking did it require to make it work on mobile?

1 Thank

I’m not totally sure, since I haven’t tried it on a phone yet… I need an extension to activate the themes, but mobile browsers don’t allow extensions.

However, that said, getting it to work in the mobile preview mode didn’t require many changes. I think I only had to add or change about 10 lines.

1 Thank

How do i try mobile version?

No clue, sorry. Maybe the Firefox “beta” version can install extensions? Most mobile browsers can’t, so they can’t use these themes yet. However, they should be available natively on the server at some point, so you could just change the theme in your BLF account preferences.

If you can get Stylus working in your browser though, it should be installable using the instructions in the first post. It’s just tricky to get the extension installed.

Hopefully I’ll find time soon to see if I can integrate @ToyKeeper and @LuxWad’s themes into the forum and make it selectable in the user preferences, then it would work for mobile too.

3 Thanks

Just a few more screenshots, showing some different views…

The editor in night mode. Also, the “last visited” marker, and the minimized timeline progress bar.

Another night mode shot, just viewing an old thread. This shows a wider view than prior shots; it can extend pretty wide before it starts putting space on the sides. Also, the shadows really make it look like each post is a separate card floating above a dark backdrop.

Day mode, with a few regular posts and the timeline slider themed to look more like a scrollbar. Embedded posts are inset to make it clear they’re contained within a parent post.

It has been a while since I did any stylesheets, so I’m having fun. There aren’t many parts of the site left to theme though, so I think it’s getting close to done.

2 Thanks

I’m super impressed with the screenshots @ToyKeeper , thanks so much for your help.

2 Thanks

I finally got around to adding these themes server-side on a testbed instance. It looks like they apply fairly cleanly and generally seem to be very close to what @ToyKeeper intended. The only error was with this single line:
.contents.ember-view, /* front page topic list */
The Ember.js framework generates CSS dynamically, so CSS rules for Ember elements can’t be specifically defined. I imagine that’s the reason for the problem with vertical centering of some of the information in the Topics (Latest) list:

Would there be a generic non-Ember selector for those frontpage elements?

Another little problem (at least in this server-side implementation) is the N / T post indicator in the timeline slider that is missing the T total value.

I haven’t played around much with the color scheme, not sure yet if I’ll add the color definitions directly into the Theme Component (which would require two copies of the theme for Light vs Dark mode since the colors would come directly from the theme and not from a separate named color scheme) or if I’ll try to add a named color scheme to go with TK’s layout CSS.

1 Thank

I tried to find one originally, and failed, but I’ll have to look again.

(edit: okay, that wasn’t too difficult… fix uploaded)

I noticed that was getting cut off sometimes, and fixed it. The code is updated on github.

The update also includes several other things, like I finally got around to doing the search page and top-right user menu:

Things aren’t 100% done yet, but it’s really close. Here’s what’s left:

  • There are some things to merge in from LuxWad.
  • I don’t have a flat dark or flat light theme included yet… just a flat dark-brown plus my two not-flat themes.
  • The code could really stand to be cleaned up. It’s a mess.

Also, given how specific I had to be about some parts of the stylesheet, and how my conceptual structures didn’t match the parent theme’s, I wouldn’t be surprised if some things break when the server is updated… and I wonder if it might be better to make a full Discourse theme instead of just doing overrides. But that’s probably a task for later, a thing to find out when upgrades happen.

Some of the methods Discourse’s stylesheets use are … brittle. Not using elements as they’re intended to be used. Like, the timeline scrollbar, for example… the scrollbar track is the left border of a div, and the handle uses a negative margin to move it outside its regular drawing area. And that’s not my own personal jank; it’s how Discourse’s code does it.

More generally, the upstream code has a lot of things hardcoded, or abstracted in ways which are prone to problems and unexpected interactions. Like, it mostly themes based on primary color, secondary color, tertiary, quaternary… and variations of each. And it makes sense from an artist’s view, since they just have a few colors to decide on. But from an engineering viewpoint, it would be far more robust to give each element its own element-specific color variable… and then have 2 layers in the theme palette – one to define the primary/secondary/etc colors, and a second layer to map those colors to the specific elements they are meant to apply to.

In lieu of dropping a massive and invasive patch on the Discourse devs to fix that though, I mostly just tried to style things locally. Like, buttons aren’t “primary high on secondary low” color any more… they’re “button foreground on button background”. And then those symbols can be made to refer to a “primary/secondary” symbol, or just given a color directly.

Long story short… I can see why nobody has made Discourse themes like this before. I had to go against the grain pretty hard to make half of it work. So you’re going to have, at the very least, a very different-looking site than all the other Discourse forums out there.

3 Thanks

@ToyKeeper
Thanks you for your hard work!
Also, thanks to @LuxWad ! :yum:

2 Thanks

Looking good!

It looks like the styled scrollbars disappeared on Firefox with the latest commit. They were working on 0c6af8a . They do still work in Chromium. (Again this is with the CSS applied server-side).

Apart from that I’m not sure if the vertical alignment in the Replies and Last Post columns is as intended, or is it an anomaly of applying the CSS on the server-side? It looks a bit different in Chromium+Stylus on the production website:


I noticed this too. That’s why the contrast of some of the elements isn’t too great as some users have pointed out. I set the main and secondary, tertiary etc. colors, but then some of the elements have a --low and --mid programatic variation of those defined colors, which are often less than ideal for contrast.

Again, thanks for your hard work, you took on a formidable task!

i wonder if this kind of discussion/suggestion is happening on https://meta.discourse.org/ – if not, maybe someone should start a thread there?

as someone in the very early stages of evaluating packages to migrate my exiting phpbb community to (at this point, i’m down to discourse and xenforo), i’ve been following this (and the migration in general) with interest. your styling brings discourse much closer to what i’d like. discourse default theme is so flat and low contrast…

@sb56637 to what extent does applying this kind of styling increase the maintenance/upgrade burden, and how are you applying it server side? are you making a new theme?

also, how are you injecting the ‘My Links’ elements into the sidebar?

Hi there @SYZYGY .

Great question, it’s always good to take that into account before undertaking changes like this. In this case I’m not making a new theme, and I expect the additions to survive future updates from Discourse. Basically here’s how configuration works in Discourse:

  • Themes are all-inclusive, with HTML and CSS that affects the layout and can add/remove visual elements. The default BLF theme is “Sam’s Simple Theme” from one of the Discourse co-founders. When using properly supported 3rd-party themes like this they can be update automatically from their upstream source independently or in tandem with a Discourse core update, but always remain independent (i.e. a Discourse update doesn’t overwrite them). This isn’t the case with some forum platforms, so keep an eye on that.
    • Theme components can be created from upstream repositories or created from scratch, and they can be associated independently with any or all of the installed themes. They allow for applying CSS rules that will override the rules if they already exist in the base theme that is in use. If there are absolute color definitions defined these will override the Discourse color scheme that is in use. They can also inject JS into different sections of the page.
  • Color schemes define a small selection of color variables, and most themes obey them and/or use lighter versions of those base colors for some elements. Color schemes can be married to themes and the user can choose them independently of the theme.

So to apply TK’s “theme” (which is actually a massive set of CSS rules, and not the same as a Discourse theme) I first installed a duplicate copy of “Sam’s Simple Theme” (which will continue to receive updates whenever he commits them) and renamed it to “ToyKeeper’s Theme”, and then I created a new theme component associated with “ToyKeeper’s Theme” and in the theme component I simply pasted in TK’s CSS rules into the GUI for CSS overrides in the theme component.

That would be this monstrosity here. It’s actually inspired by the cleanest and most effective code example I could find on Discourse Meta for accomplishing a similar task, but it’s still really ugly because we’re still in the early days of the Discourse sidebar and it’s not set up yet for customization. The following code gets added to the “Head” section of a theme component that I associated with the default BLF Theme to add all sorts of random tweaks and overrides:

<script>

const links1 = [
    // FontAwesome icons may need to be added in the site settings if they don't correctly appear
    { title: "BLF Rules", src: "/rules", icon: "gavel" },
    { title: "Commercial Sellers", src: "/commercial", icon: "gift" },
    { title: "Related Sites", src: "/related-sites", icon: "globe" },
    { title: "Contact the Admin", src: "/new-message?username=sb56637", icon: "envelope" }
]
const links2 = [
    // FontAwesome icons may need to be added in the site settings if they don't correctly appear
    { title: "My Activity", src: "/my/activity", icon: "" },
    { title: "My Participation", src: "/search?expanded=false&q=in%3Aposted%20order%3Alatest", icon: "" },
    { title: "My Watched Threads", src: "/latest?order=activity&state=watching", icon: "" },
    { title: "My Tracked Threads", src: "/latest?order=activity&state=tracking", icon: "" }
]

$(document).ready(function () {
    if (document.getElementById("toggle-hamburger-menu")) {
        // We're in mobile view
        addToggleListener(document.getElementById("toggle-hamburger-menu"))
    } else {
        // We're in desktop view
        addToggleListener(document.getElementsByClassName("btn-sidebar-toggle")[0])
        addCustomLinks1()
        addCustomLinks2()
    }

    function addToggleListener(toggleEl) {
        if (toggleEl) {
            toggleEl.addEventListener("click", function () {
                // Wait a bit for the sidebar to load
                setTimeout(function() {
                    let sidebar = document.getElementsByClassName("sidebar-section-header").length
                    if (sidebar) {
                        addCustomLinks1()
                        addCustomLinks2()
                    }
                }, 100)
            })
        }
    }
    
    function addCustomLinks1() {
        // Wait a bit until navigation has been loaded
        setTimeout(function () {		
            const parentEl = document.getElementsByClassName("sidebar-section-content")[0]
            let linksAlreadyAdded = document.getElementsByClassName("sidebar-section-custom-link1").length
        
            if (parentEl && !linksAlreadyAdded) {
                links1.filter(function (link) {
                    let linkDiv = document.createElement("li")
                    let linkTitleTrim = link.title.replace(/\s+/g, '')
                    linkDiv.className = "sidebar-section-link-wrapper sidebar-section-custom-link1"
                    linkDiv.innerHTML = `<a href="${link.src}" class="sidebar-section-link sidebar-section-link-everything sidebar-row ember-view">
                            <span class="sidebar-section-link-prefix icon" id="link_${linkTitleTrim}"></span>
                            <span class="sidebar-section-link-content-text"> ${link.title} </span>
                        </a>
                      `
                    parentEl.append(linkDiv)
                    
                    let linkIcon = document.getElementById("link_" + linkTitleTrim)
                    if (linkIcon && link.icon) {
                        linkIcon.innerHTML = `<svg viewBox="0 0 640 512" class="fa d-icon svg-icon prefix-icon svg-string d-icon-${link.icon}" xmlns="http://www.w3.org/2000/svg">
                                <use xlink:href="#${link.icon}"></use>
                            </svg>
                        `
                    }
                })
            }
        }, 100)
    }
    
    function addCustomLinks2() {
        // Wait a bit until navigation has been loaded
        setTimeout(function () {
			
			const customHeader = document.createElement("div")
			customHeader.className = "sidebar-section-wrapper sidebar-section-blf"
			customHeader.innerHTML = `
				<div class="sidebar-section-header-wrapper sidebar-row">
				<span class="sidebar-section-header-caret">
                    <svg class="fa d-icon d-icon-angle-down svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#angle-down"></use></svg>
                </span>
				  <button id="ember11" class="sidebar-section-header sidebar-section-header-collapsable btn-flat btn no-text" type="button">
					<span class="sidebar-section-header-text"> My Links </span>
				  </button>
				</div>
				<div class="sidebar-section-blf" id="customNavigation"/>
				`
							
			const sidebar = document.getElementsByClassName("sidebar-sections")[0]
			sidebar.prepend(customHeader)	
          
          
            const parentEl = document.getElementsByClassName("sidebar-section-blf")[0]
            let linksAlreadyAdded = document.getElementsByClassName("sidebar-section-custom-link2").length
        
            if (parentEl && !linksAlreadyAdded) {
                links2.filter(function (link) {
                    let linkDiv = document.createElement("li")
                    let linkTitleTrim = link.title.replace(/\s+/g, '')
                    linkDiv.className = "sidebar-section-link-wrapper sidebar-section-custom-link2"
                    linkDiv.innerHTML = `<a href="${link.src}" class="sidebar-section-link sidebar-section-link-everything sidebar-row ember-view">
                            <span class="sidebar-section-link-prefix icon" id="link_${linkTitleTrim}"></span>
                            <span class="sidebar-section-link-content-text"> ${link.title} </span>
                        </a>
                      `
                    parentEl.append(linkDiv)
                    
                    let linkIcon = document.getElementById("link_" + linkTitleTrim)
                    if (linkIcon && link.icon) {
                        linkIcon.innerHTML = `<svg viewBox="0 0 640 512" class="fa d-icon svg-icon prefix-icon svg-string d-icon-${link.icon}" xmlns="http://www.w3.org/2000/svg">
                                <use xlink:href="#${link.icon}"></use>
                            </svg>
                        `
                    }
                })
                let theUl = document.createElement("ul")
                theUl.className = "sidebar-section-content"
                parentEl.append(theUl)
            }		
        }, 100)
    }

})
</script>

Oh, and it also requires some CSS overrides too in the same theme component :

.sidebar-section-categories {
  display: flex; /* Setup a flex layout so you can reorder things */
  flex-direction: column;
  order: +1;
}

.sidebar-section-tags {
  display: flex; /* Setup a flex layout so you can reorder things */
  flex-direction: column;
  order: +1;
}

.sidebar-section-blf {
  display: flex; /* Setup a flex layout so you can reorder things */
  flex-direction: column;
  order: +1;
}

.sidebar-section-content {
  display: flex; /* Setup a flex layout so you can reorder things */
  flex-direction: column;
  .sidebar-more-section-links-details {
    order: +1;
  }
}

.sidebar-section-message {
    display: none;
}

.sidebar-wrapper li a.sidebar-section-link-about {
    display: none;
}

.sidebar-wrapper li a.sidebar-section-link-faq {
    display: none;
}

.sidebar-more-section-links-details-content-secondary .sidebar-section-link.sidebar-section-link-about {
    display: none;
}

.sidebar-more-section-links-details-content-secondary .sidebar-section-link.sidebar-section-link-faq {
    display: none;
}
2 Thanks

Looks interesting, thank you!!

1 Thank

thanks a lot. i will definitely be referring to this later.

i’m in the process of doing ‘minimal-effort’ migrations to this and xf to play with them. both are lightyears ahead of phpbb…

nice job on your migration btw. the only thing i miss is my list of subscribed threads (or whatever it was called) from the old site. i subscribed to some threads that i never posted in kind of abusing it as a bookmark feature. that, and i can’t believe i’m saying this… i liked the old site’s theme better than sam’s simple discourse theme. but the new ‘theme’ in progress looks pretty dang good. i might use it as inspiration if i go with discourse.

2 Thanks

also, have you considered moving the All categories element to the top of the Categories list in the sidebar?

i also somehow feel that the My Links elements should be inside of the Community list instead of in a list of their own. that would make it more native feeling (inside of a legit, collapsing list), and it feels more fitting to me to have them directly adjacent to the Everything and My Posts elements.

jmo, ofc :slight_smile:

Yeah, I think I know why too. One of the variable names I used turned out to be a thing upstream Discourse uses for a different purpose, so I had to rename it… but I missed a reference to it while refactoring. It’ll be fixed shortly.

Nope, that doesn’t look how it’s supposed to. That part of the style is particularly brittle, since it tries to rearrange items to be different than the actual markup, and to do this, it floats them. I’ll have to see if I can fix that somehow. That’s the sort of thing a proper theme would probably be able to do much more easily.

I don’t have access to the server, but I can at least test things on other Discourse sites to see if anything weird happens… so for now I’ll plan on testing stuff that way. I already found a couple things to fix by applying it to other sites, and I also found that it works when applied to the default Discourse “Light” and “Dark” themes… so that’s a good sign that hopefully it’ll keep working for a while.

Looking around in the Discourse theme collection, it looks like nobody has really done anything like this before. So I’m probably going to send it upstream and see what happens. Ideally I’m hoping one of the devs will like it enough to accept patches and then maintain it so I won’t have to.

3 Thanks

Hi there, sorry that adds additional hassle for you. I can imagine those floated rearranged items must be quite a challenge, I’m impressed you got it that far. When you use your CSS modifications with Stylus on BLF does it sometimes or always have that same alignment issue too? Or did I do something wrong? (This screenshot was taken with Chromium+Stylus on the production website with no server-side changes. I just copy/pasted your style.css and tk-sky-candy.css into Stylus.)

1 Thank