SamSuka
Touhou-Project.com
Touhou-Project.com

patreon


Looking ahead as many times as you like

One of the amazing and genius new features of the last round of site updates is the ability to preview posts. Today I wanted to take the chance about why this was implemented and how.  

It’s something that’s been suggested from time to time, most notably by people who don’t really understand a site like THP works. Luckily for you, I’ve peered into the abyss and have something of a notion about how it all comes together. In very broad sweeps, two processes happen when you hit submit on your latest vote for your favorite touhou: the post information is processed and put into a proper format and stored then that information is retrieved and assembled by the board software using templates to generate the HTML rendered by your browser.  

Right, if you’re minimally aware of internet and how to computers that should make sense. If not, sorry. I will use some colorful analogies for other parts so try to read on.  

So previewing posts need to happen at the first general process, right? I mean it makes no sense for something that’s not permanent to be stored on the server. So, for the most part, any attempt to introduce the feature would overlook all the (pretty complicated) magic that goes on when a board page is generated. So, again generalizing, there’s two real ways you can go about that: either mimic the process client side or have as much of it happen on the server side as possible.  

The former has the advantage of not interacting with the ill-documented code on the site’s end but the disadvantage of being a grope in the dark. Not to mention increased code complexity on the user’s side. I’m of the school of thought that scripts should be as light and to the point as possible. I hate sites that have several megabytes of javascript to render everything. So almost by default that meant that I was inclined to do the latter.  

The problem with that, as you might imagine, is figuring out just how the hell the site does what it does. There’s a central file that takes the information in the post box and does stuff with it. Problem is, a lot of that information is separated and treated by special classes elsewhere in other files and it’s not always clear why that’s happening. A lot of it has checks for legacy features or things that don’t really concern us, like upload boards. So really, step one was to pare down this central hub into more manageable essentials.  

Time-consuming doesn’t even begin to cover what all this was like. Checking a variable to see when it’s set, what functions or classes use it and then what happens every step of the way is akin to following various assembly lines at once while being on a rollercoaster (see? told you that it’d be colorful). Some things are obvious when you’re careening up in the air; rss feeds and code related to checks for deleting images are evidently not necessary when you’re just trying to get a fake post to go through.  

Eventually, with enough time and the odd shot of liquid courage, I was able to have a somewhat clear picture of the data I needed and how it would be processed. Even then that wasn’t a matter of plugging into existing code. A lot of this is down to the many checks the site does for whatever reason. Posting a new thread without an image? Using sage in the email field? The board locale is not english? Special bits of code are executed and often you’ll get exceptions and error screens that tell the poster how they’ve messed up. This can’t be readily decoupled from the functions that do the data processing meaning that if you intend to reuse the site code for a fake post you need to make a decision:

Either rewrite many of these functions just for the previewing or accept their lovely idiosyncrasies.  

I chose the latter again, trying to minimize the conditions where there’d be an error by how the information was taken from the submitted post in the first place. The result is that things work well 95% of the time but there may be the odd error or two that will confound a few damned souls. Given that you can just keep previewing posts, that’s fine though. And when you try to push through an actual post, it’ll do all its regular checks and tell you what exactly is wrong.  

Part of the challenge was learning how to pass the data asynchronously from the user side to the new post preview processing PHP (try saying that a couple of times fast). As both JS and PHP are a little fast and loose with how they categorize types of data. Some checks were a little fiddly to get right but I managed to create a mostly coherent way of making sure the data was in the correct form.  

Of course, even when processed, you then have to get the information that has been checked for special characters, emails and what have you not, returned in a way that can then be pasted into the site. There’s actually three different ways the data can be formatted and returned. Once if it’s a “new thread”, another if it’s a reply to a thread on the board page and yet another if the page is a whole thread. Then you need checks whether or not an image was passed. That changes how it’ll look, obviously.  

Initially, I opted for a static placeholder image in all cases but with the update a few days ago, witchcraft happens and the image you set in the image choose actually gets put in as a thumbnail. Go ahead, try it now, I’ll wait. Satisfied? Yeah, it’s pretty cool. But also really tricky to get right as it depends on a lot of browser functionality that isn’t that well documented or necessarily implemented uniformly across browsers. I honestly don’t know if it works in, say, Edge, or the newer Opera versions. You just have to target the most popular and compliant browsers and hope for the best. Otherwise you’re liable to be consumed by madness. You’ll at least see the placeholder image if it doesn’t work, so it’s fine.  

You can keep a secret, right? Just between you and me, it’s not a completely faithful representation of what happens with a final post. This is because the thumbnail that’s generated is done locally, with some css trickery, instead of being processed server-side. Doing it server-side would increase code complexity and have to involve temporary files that are then deleted. How would one even manage that? Delete everything in that temp directory every couple of minutes? And what if you realize you keep messing up your post and preview multiple times? Seems wasteful, resource-wise.  

And then there’s clever little bits of code in there that I snuck in to make life a little bit more worth living. Like when you preview what would be a new thread or a long reply, clicking on the “the message is too long” bit expands that message fully. I felt that was necessary to have because, as this data only temporarily exists in the client side at the end, it’s not really possible to open a thread and see this fake post. Another cool attention to detail is the fact that it’ll add a post to a thread on the board and remove the first of the visible replies if there’s three. If there’s less, it’ll just add normally. The intention is to make it as indistinguishable from a real post as possible.  

Even with all these limitations and workarounds, this is another part of the code I’m proud of getting done. I certainly learned a lot and there were even moments where I had fun. Not sure it offsets the moments of frustration and tedium when I had to test a lot of work in progress code and hope nothing broke. But that’s the thing about rollercoasters: they’re not exciting all the time.  

No idea how much people will use this but I hope that it’s useful. Even if it was time-consuming and labor-intensive, it’s my hope that it helps THP become as great as it possibly can be.


More Creators