Welcome: How this site was created

Welcome to my personal website and blog! This is not my first website ever, but it is the first one that I write the backend code myself (I have made a few frontend apps). In this first article on the blog, I feel like I should share a bit about how I made the site.

Picking the technologies

The only things I have touched when I made the previous websites were PHP-based applications, like MediaWiki, running on an Apache-based server. This time around, the host I am on uses nginx, whose configuration opens a port that I can hook into to serve the site. So, I felt I could deploy something different. Out of the languages I am comfortable with, two stood out the most as potential web backends: Python, and JavaScript. I am more used to languages that derive their syntax from C, namely C++, C#, Java,..., so my final choice was JavaScript, running on NodeJS, of course.

My experience with NodeJS could not be said as diverse. The only useful thing I did with it was to contribute a small feature into Monkeytype, so I don't know much about the various libraries used there. However, I have been hanging out and helping people on Discord in various languages, including JavaScript, so I had the opportunity to know about Express. I glanced at its documentation and making a web server was shown to be really simple, so I made it my choice.

Then I needed a format, a markup language, to write my blog posts in, as plain text as you can imagine would barely give the content any chance to express itself. About this, what language is more prevalent than Markdown. I have made quite an amount of GitHub repositories, as well as writing thousands of messages with formatting on Discord, so it is no stranger to me.

About the storage, I am the most familiar with the MySQL database management system. Too bad though, the host this time doesn't have it configured; it has ClickHouse instead. From reading a bit about ClickHouse, it also supports SQL(-like) syntax, but it isn't designed for quite the same purpose as MySQL was. The primary purpose of ClickHouse is to gather data, a lot of data, and then query out aggregating information from them, which normally happens a lot less often. One can immediately relate this to an operation that is done on web application systems: analytics. But it's the best I have and I didn't imagine I would have a huge dataset in there to slow it down so I accepted to move along.

For the frontend, I am not anywhere near a great designer, so I opted for a very simple design, the result of which you are seeing right now. With such a design, I didn't feel the need for any kind of frontend framework; both HTML, CSS and JS have evolved to a point where I can quite easily create what I want, examples of which are the frontend apps that I have made.

So in summary, the web stack I have is: ClickHouse, NodeJS, Express and VanillaJS. Put the first letter of each of those names together and we have an acronym CNEV. Doesn't sound as nice as "LAMP" or "MERN", but still pronounceable.

Growing the server

The first thing to do was making the home page for the website. This would contain mostly static information about myself, so I chose to write a plain index.html file. Conveniently, Express provides a built-in plugin to serve static files, so it was a no brainer to bring it as a starter to the index.js script that would be run to serve the site:

app.use(express.static(root + "web"));

Then it took an hour or two to write the HTML code along with the CSS files that would make it look decent. One file was main-styles.css with styles that would apply across the whole site, and one index.css contained styles unique to that home page.

Running the server to test was then as simple as:

node .

Then I typed the IP of the server to the browser's address bar and I saw the home page. Then I switched to the next thing to do: pointing my own domain to the server. Not directly though, I don't have the expertise to deal with the potentially dangerous wilderness out there, so I hit Cloudflare. Setting the domain up was a few clicks' process, and then I could access the home page through leduyquang753.name.vn.

Then the next task was back to developing the backend, which was building the blogging system. The web page that would display each blog post would have the same sort of outline; the only things that would change would be the post's title, timestamp and content. This hints to a templating system. Express itself has a page with a rather long list of template engines; after glancing a few of them, my eyes got caught into Embedded JavaScript. It uses the style of <% %> to enclose JavaScript code to run when rendering the page, much like PHP's <?php ?>, so I went straight with it. I wrote the blog post template into a .ejs, with some simple <%= variable %> tags sprinkled in to put the post's information into.

The page's title and timestamp were as easy as putting it in literally or through a bit of formatting code, but the post content, using Markdown, was of course much more complicated than that, so I called in markdown-it. After instantiating an instance with the necessary configuration, it was just md.render(postContent).

Then came styling the blog post page. Markdown mostly expands into simple HTML tags, so styling them was easy with a blogPost.css. For blocks of code, I just used highlight.js like anyone else, styling for which was also not very complicated, thankfully, although it took a bit longer to write a syntaxHighlight.css.

In continuation was setting up the database to store the blog posts' data. I did nothing fancy with it either, creating two tables, one for posts and one for their content's revisions, as I felt like I wanted to save the history should I need to make edits. Each row of the revisions table has a type column which allowed me to store both post titles and post contents' history.

Writing up the backend code to serve the blog was easy, too. First declare an app.get entry through the /blog route, then query the database for the data, then feed it into ejs.render along with the blog post template, and the rendered blog post page was ready to be sent to your browser.

Then I would like to have the home page to display the latest blog entries. So it could no longer be a simple, static .html file as before, I transformed it into another .ejs and added a card, the only card that needs embedded JavaScript:

<ul class="blogPostList">
	<% for (const post of posts) { %>
		<li>
			<a href="/blog/<%= post.url %>"><%= post.title %></a>
			<time datetime="<%= post.timestamp %>">• <%= post.date %></time>
		</li>
	<% } %>
</ul>

There was also the part about making the site's content management interface, but it goes into the area of information that shouldn't be shown publicly, so I won't tell about its making here. It's not complicated either, though.

Conclusion

So, my little personal website is designed plainly and also implemented very simply. I am sure there are some who would look at the site and lament about its plainness, but this is just my personal taste. And there is no reason to make the backend complicated either. Lurking around on Discord reveals to me a trend nowadays that a web site uses any fancy framework that has just come about, even in cases when the same thing could be not that much harder to achieve without them, which creates unnecessary bloat. I like the beauty in simplicity. And I hope that this can be another example into the collection of things that don't need much, as long as they work and serve the intended purpose.

Discuss on Mastodon