My WordPress Template 2024 made from Vite and TypeScript

My WordPress Template 2024 made from Vite and TypeScript

Hi there😊
I’m Yuichi, a CCTB student and a Frontend developer.

I created new WordPress template for practical work.
It is assumed that making WordPress site from scratch.
I will share the template and its idea.

【Repository】: https://github.com/YuichiNabeshima/my-wordpress-template

Things I want to do on this template

Do not use any JavaScript framework, keeping basic usage as WordPress.
Do not use UI framework for handling various design.
Each pages load CSS and JavaScript scripts as much as the page needs for reducing file size.
I want to use Vite for bundling.
I want to split JavaScript scripts as a file as each feature.

Directory structure

Main directories are these three.

public is put the static files like font or image.

src is put the codes needing build and compile, like CSS using post-css or TypeScript.

wp is put the production codes. When you deploy, you upload only this directory to production server.
The assets of public and src will be output under the wp/assets/ after build command.

┣━ public ━ img/
┃ ┗━ fonts/

┣━ src ━━━━ css/
┃ ┗━ ts/

┣━ wp ━━━━━ assets/
┃ ┣━ index.php
┃ ┣━ front-page.php
┃ ┗━ …

Local environment

It uses wp-env for the local environment.
It is very easy to set up and no configuration.
We can check own site to http://localhost:8888 on web browser.

Strategy of entry point

JS and CSS should be loaded as much as necessary for the page in order to reduce the file size as much as possible.
In other words, it is assumed that every page has its own JS and CSS.
Of course, if you can share files between pages, do so (like common.js)
Each file put under the entry_point directory will be output under /wp/assets/ with the file name unchanged after build.

After build …

You need to add the arguments of get_header() and get_footer() for loading the each builded file.

<?php
get_header(null, [
‘css’ => ‘top’,
]);
?>
<?php
get_footer(null, [
‘js’ => ‘top’,
]);
?>

Developing

Since I am using Vite, I want to use Vite’s extremely fast development server.
Therefore, I have devised tags that load CSS and JS.

/wp/header.php

<?php
if( WP_DEBUG && IS_DEV ):
?>
<link rel=“stylesheet” href=“http://localhost:5173/src/css/entry_point/<?=$css?>.css”>
<?php
else:
?>
<link rel=“stylesheet” href=<?=get_stylesheet_directory_uri()?>/assets/css/<?=$css?>.css”>
<?php
endif;

/wp/footer.php

<?php
if( WP_DEBUG && IS_DEV ):
?>
<script type=“module” src=“http://localhost:5173/@vite/client”></script>
<script type=“module” src=“http://localhost:5173/src/ts/entry_point/<?=$js?>.ts”></script>
<?php
else:
?>
<script src=<?=get_stylesheet_directory_uri()?>/assets/js/<?=$js?>.js”></script>
<?php
endif;

During developing, we can benefit from Vite’s development server by referencing http://localhost:5137.
When I start the Vite development server, what I see in my browser is http://localhost:8888.
http://localhost:5173 shows nothing

WP_DEBUG variable

The WP_DEBUG variable in if statement is set to true in wp-env.json, so even if you accidentally deploy with IS_DEBUG set to true, it will not enter debug mode.

IS_DEBUG variable

The IS_DEBUG variable is a global variable that you manually set in functions.php.
The default is true, so the local environment refers to the Vite’s development server.
If you want to check the built JS and CSS in the local environment, please set it to false.

Styling

CSS concept

The reason of CSS is difficult is because the scope is always global.
Therefore, I want to propose that you don’t have to make CSS commonly, put the CSS codes for each pages.
When the number of common CSS increases, in many cases, you will spend a lot of time searching for a class of common style somewhere when you add new page.
When the number of common CSS increases, in many cases, you will spend a lot of time for searching a class of common style when you add new page.

CSS directory structure

┣━ CSS ┯━ common ━━━━━┳━ reset.css
┃         ┃                          ┣━ base.css
┃          ┃                          ┗━ variable.css
┃          ┃
┃          ┣━ entry_point ┳━ top.css
┃   ┃                          ┗━ about.css
┃          ┣━ mixin ━━━━━━━━ media.css
┃          ┗━ page ━━━━━━━┳━ top.css
┃                                      ┗━ about.css

As mentioned above CSS creates a single file dedicated to each page.
The CSS files under the entry_point gather all the CSS codes like below.

@import ‘../mixin/media.css’;

@import ‘../common/reset.css’;
@import ‘../common/variable.css’;
@import ‘../common/base.css’;

@import ‘../page/top.css’;

The main styles of the page are put in the CSS file under page.

There are some things you really want to commonly, such as common layouts, headings, and buttons.
In that case, please make an appropriate file under the mixin directory and import it to entry_point.

┣━ mixin ┯ button.css
┃ ┗ layout.css

/src/css/entry_point/top.css

@import ‘../mixin/media.css’;
@import ‘../mixin/button.css’; // import here

@import ‘../common/reset.css’;
@import ‘../common/variable.css’;
@import ‘../common/base.css’;

@import ‘../page/top.css’;

/src/css/page/top.css

.btn {
@mixin btn;
}

JS

I will explain how to add JS feature in this template.

JS directory structure

┣━ ts ┳━ entry_point/ ━━ top.ts
┃        ┣━ modules/ ━━━━━━ alert.ts
┃        ┗━ register_module.ts

How to add JS feature

First, add the data-module attribute to a HTML tag, which is the starting point of the event firing.
The value of data-module is assigned the function name which you want to add as JS feature(this will be explained later).

<button
class=“btn”
data-module=“alert”
>alert</button>

Next, create a ts file for the feature you want to add under /src/ts/modules/ and define the function in it, example is below.

/src/ts/modules/alert.ts

export function alert( el: HTMLElement ) {
el.addEventListener(click, () => {
alert(click button!);
});
}

The argument of the function will be passed the DOM which you assigned the data-module attribute before, so you can use the DOM for making feature, like add event.

Finally, register the created function in the file under entry_point

/src/ts/entry_point/top.ts

import { registerModule } from ../register_module;
import { alert } from ../modules/alert;

registerModule({
alert,
});

That’s it! You can use JS feature you created.

Pass the value from html

If you want to pass variables from html, pass them in json format to the data-options attribute.
Anything other than json will result in an error.

/wp/front-page.php

<button
class=“alert-btn”
data-module=“alert”
data-options=‘{
“alertText”: “I am from earth.”
}’

>
Alert!
</button>

/src/ts/modules/alert.ts

type Opts = {
alertText: string;
}

export function main( el: HTMLElement, opts: Opts ) {
const msg = opts.alertText;
el.addEventListener(click, () => {
alert(msg);
});
}

Responsive

If you want to only run the module when device is PC or Smart phone.
You can use data-only attribute, there are 2 options which pc or sp.

Display width

pc >= 768px

sp < 768px

<button
class=“alert-btn”
data-module=“alert”
data-options=‘{
“alertText”: “I am from earth.”
}’

data-only=“pc”
>
Alert PC only!
</button>

When you want to put multiple modules on a tag.

<button
class=“alert-btn”
data-module=“alert another-alert”
data-options=‘{
“alert”: {
“alertText”: “message”
},
“another-alert”: {
“afterText”: “after message”
}
}’

data-only=‘{
“alert”: “pc”,
“another-alert”: “sp”
}’

>
Multiple module
</button>

How was my new WordPress template? I would be happy if you could use it and give me feedback if you like!

I am looking for a job

As of July 2024, I am looking for a job.
My areas of expertise are React, TypeScript, Remix, Next, PHP, and WordPress.
I’m currently a student, so I’m looking for a part-time position where I can work up to 20 hours a week.
I’m looking for a full-time job starting next August.

Please follow and like us:
Pin Share