The JS runtimes
Published in

The JS runtimes

DenoPress Part 2 — Decoding More WordPress Features

Assembled by the author

In Part 1, I introduced the idea of serving an existing WordPress site using JavaScript in a Deno-based server, a relatively new replacement for Node.js by its original author. My repository for this experiment is free and opensource at this link. In Part 1, we were able to successfully recreate the WordPress text and menus. Here we bring more key WordPress features to DenoPress.

Fixing CSS dropdowns

One nice thing about computers is that they let you know when you don’t really understand something. I’ve used CSS dropdown menus successfully for years, but when I tried it in Part 1 it didn’t work, because I had made the following mistake:

<li>Item 1a</li>
<li>Item 1b</li>

The error is that first </li> that I put in bold. The dropdown <ul>…</ul> must be inside the <li>. The </li> has to move outside the </ul>. Doh!

Part 2a: Featured Images

To find the url to your featured image for a post (or a page) with ID equal to param, you need to find the pointer to a linked post from the postmeta table:

select guid from wp_postmeta right outer join wp_posts on ID=meta_value and meta_key='_thumbnail_id' where post_id=${param}

That gives you the link to the fullsize copy of the image in the /wp-content/uploads/… folder which is fine for a large featured image.

Part 2b: Routing

The URL to get to any given page on a WordPress site is usually via

  1. a home page by default,
  2. /postName,
  3. /post_id=n
  4. /category/someCategory to generate a list of posts with links
  5. ?q=term.

Once DenoPress gets the URL parameters, I’ve added code to generate some of these options. For my home page, I’ve just listed the categories by their name and “slug.”

Part 2c: Listing Categories as links

The query to get all the existing categories in alpha order is:

query=`select name, slug from wp_terms a, wp_term_taxonomy b where a.term_id=b.term_id and taxonomy='category' order by 1`;

The wp_terms table seems to represent everything you might want to search across (not counting the post_titles themselves, and the taxonomy indicates what kind of term it is.

Part 2d: Listing Recent Posts by Category

For this, we need two parameters in the URL, the first (param) is in this case the word “category” and the second (param2) is the “slug” for that category.

Each post can have as many categories and tags as needed, all of which are listed in the wp_terms table, with the “one to many” relationship of posts to term handled by the wp_term_relationships table.

To list them all with the newest posts first, you use a similar query that you use to get a single post plus additional fields (like author and post_date) and additional joins to link to the category term (param2) to the posts. Here I tell the database to only give me the 10 most recent posts. (The posts_per_page is a field in wp_options which we could also use.)

`select a.post_title,a.post_content,c.guid, a.post_name, a.post_date,a.post_excerpt
from wp_posts a right outer join wp_postmeta b on a.ID=b.post_id and b.meta_key='_thumbnail_id'
right outer join wp_posts c on c.ID=b.meta_value
join wp_term_relationships e on a.ID=e.object_id
join wp_terms f on e.term_taxonomy_id=f.term_id and'${param2}' order by 3 desc limit 10`

Here is a tricky part. c.guid gives you the URL of the full-size version of the featured image. For just having fun on a local computer, that’s fine, but more likely if you are listing 10 or 100 posts, you’d like to use a smaller image file.

If you want the smaller versions — say, for a list of recent posts — you need to append the size dimensions, which are set by the theme and stored in wp_options with option_name thumbnail_size_h and thumbnail_size_w, which on my Wordpress are listed as 150. Now, I usually use the “medium” size for lists — those are listed in options also but these are not the actual size of the files but rather the maximum size. On my site, it lists both h and w as “300” but there are no files ending in 300x300! But the 150x150 files are there, so before using the c.guid url, I’ll find the final “dot” and insert “-150x150” before it.

Part 2e: Localizing embedded URLs

Domain names can change, and — in my case — I’d like to displays images and links in a wordpress database for a different domain! So, I have to detect and remove those domains.

Now, if I were writing WordPress myself, I would make sure that it didn’t include domains in the URLs for anything local. Instead of a line like:

<img src="">

… what I want is

<img src="/wp_contents/uploads/2010/05/stuff.jpg">

In my case, on my local machine, I simply created a symlink wp_contents in my /denopress folder that points to my /wordpress/wp_contents. If I were building a standalone denopress install, I would just either run it from the /wordpress folder or copy the wp_contents across.

Part 2f: Which CSS to keep?

When you look at the underlying HTML of most WordPress pages, you are likely to see many links to CSS files. After playing around, as far as I could tell the only one we need beyond my own CSS is the one for Gutenberg Blocks:


Coming Up Next! Recreating wp-admin!



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
John Coonrod

John Coonrod

A guy committed to human dignity for all.