Home >Web Front-end >CSS Tutorial >How to Build a Nearly Headless WordPress Website
Traditional WordPress themes can also run as efficiently as static websites or headless web applications. The vast majority of WordPress websites are built using traditional WordPress themes. Many of these websites even have good caching tiers and dependency optimizations, making them run fairly fast. But as developers, we have mastered ways to create better results for our websites. Using headless WordPress enables many websites to achieve faster loading, better user interaction and seamless transitions between pages.
The problem is: maintenance. Let me show you another possibility!
Let's first define what I'm talking about "traditional" WordPress, "headless" WordPress, and "nearly headless" WordPress.
Traditionally, WordPress websites use PHP to render HTML tags rendered on pages. Each time a link is clicked, the browser sends another request to the server, and PHP renders the HTML tag of the clicked website.
This is the method used by most websites. It is easiest to maintain, has the lowest technical complexity, and uses the right server-side caching tool and it also performs quite well. The problem is, because it is a traditional website, it feels like a traditional website. In this type of website, transitions, effects, and other stylish modern features are often harder to build and maintain.
advantage:
shortcoming:
Headless WordPress websites use modern JavaScript and some kind of server-side RESTful service, such as WordPress REST API or GraphQL. Instead of building and rendering HTML in PHP, it is the server sending minimal HTML and a large JavaScript file that handles rendering of any page on the website. This approach loads the page faster and provides an opportunity to create truly cool transitions and other fun features between pages.
No matter what you say, most headless WordPress sites require a developer to make any major changes. Want to install the form plugin? Sorry, you may need a developer to set it up. Want to install a new SEO plugin? No, developers need to change the application. Want to use that fancy block? Too bad – you need a developer first.
advantage:
shortcoming:
See "WordPress and Jamstack" for a more in-depth comparison of the differences between WordPress and static hosting.
I love the results that headless WordPress can create. I don't like maintenance. I want a web application that allows me to have a fast loading speed, transitions between pages and the overall app-like feel of the website. But I also want to be free to use the plugin ecosystem that makes WordPress so popular. I want something headless. Nearly headless .
I couldn't find anything that fits this description, so I built one. Since then, I've built several websites that use this approach and built the necessary JavaScript libraries to make it easier for others to create their own near-headless WordPress themes.
Nearly headless is a WordPress web development method that provides you with many of the benefits of similar applications brought by the headless approach, as well as the development ease of using traditional WordPress themes. It does this with a small JavaScript application that will handle routing and render your website like a headless application, but has a fallback mechanism that can load the exact same page with normal WordPress requests. You can choose which pages to load using the fallback method, and you can inject logic into JavaScript or PHP to determine if the page should be loaded like this.
You can see how it actually works on the demo website I built, which shows what this approach can achieve.
For example, a website implementing this method sells WordPress courses online using a learning management system called LifterLMS. This plugin has built-in e-commerce features and has the necessary interface to set up hosting course content and put it behind a paywall. This site uses a lot of built-in features of LifterLMS – a large part of which is checkout cart. Instead of rebuilding the entire page to work in my application, I simply set it up to load using the fallback method. So this page works like any old WordPress theme and therefore works exactly as expected – all without me rebuilding anything.
advantage:
shortcoming:
To be nearly headless, it requires the ability to perform multiple actions, including:
This allows the website to take advantage of progressive enhancement . Since the page can be viewed with or without JavaScript, you can use the most appropriate version based on the requests you made. Is there a trusted bot crawling your website? Send them a non-JavaScript version to ensure compatibility. Is there a checkout page not working as expected? Temporarily force it to load without an application and fix it later.
To complete these projects, I released an open source library called Nicholas, which includes a prefabricated boilerplate.
The biggest problem I want to overcome when building a near-headless application is to keep the page rendering consistent in how it is in PHP and JavaScript. I don't want to build and maintain my markup in two different places - I want to use as much single source code as possible. This immediately limits the JavaScript library I can actually use (sorry, React!). After some research and a lot of experiments, I ended up using AlpineJS. This library keeps my code DRY plausible. Some parts absolutely have to be rewrite for each part (e.g., looping), but most important markup blocks can be reused.
A single post template rendered using PHP might look like this:
<code><?php if ( have_posts() ) { while ( have_posts() ) { the_post(); if ( is_singular() ) { echo nicholas()-?>templates()->get_template( 'index', 'post', [ 'content' => Nicholas::get_buffer( 'the_content' ), 'title' => Nicholas::get_buffer( 'the_title' ), ] ); } } } ?></code>
The same post template rendered using Alpine's JavaScript:
<code><template :key="index" x-for="(post, index) in $store.posts"> = niccholas()->templates()->get_template( 'index', 'post' ) ?> </template></code>
They all use the same PHP template, so all the code inside the actual loop is DRY:
<code>$title = $template->get_param( 'title', '' ); // 获取传递到此模板的标题,回退到空字符串。 $content = $template->get_param( 'content', '' ); // 获取传递到此模板的内容,回退到空字符串。 ?></code> = $title ?> <div x-html="content">= $content ?></div>
Related: This Alpine.js method is mentally similar to the Vue.js method introduced by Jonathan Land in "How to Build Vue Components in WordPress Theme".
"Compatibility Mode" allows you to force any request to load without running a headless version of JavaScript on your website. When the page is set to load in compatibility mode, the page will only load in PHP and the application scripts will never queue. This allows the "question pages" to run without rewriting anything that doesn't work as expected when using the app.
There are a number of different ways you can force the page to run in compatible mode – some require code and some do not. Nicholas adds a toggle switch to any post type that forces posts to load in compatibility mode.
Apart from that, you can manually add any URL to force it to load in compatible mode in Nicholas settings.
These are a good start, but I found that I can usually automatically detect when the page needs to be loaded in compatibility mode based on the blocks stored in the post. For example, suppose you have Ninja Forms installed on your website and you want to use the validation JavaScript they provide instead of recreating your own JavaScript. In this case, you must force compatibility mode to be used on any page that contains Ninja Form. You can manually add each URL one by one, or you can use a query to get everything on the page with a Ninja Forms block. For example:
<code>add_filter( 'nicholas/compatibility_mode_urls', function ( $urls ) { // 过滤Ninja Forms块$filtered_urls = Nicholas::get_urls_for_query( [ 'post_type' => 'any', 's' => 'wp:ninja-forms/form', // 查找Ninja Forms块] ); return array_merge( $urls, $filtered_urls ); } );</code>
This automatically adds any page containing the Ninja Forms block to the list of URLs that will be loaded using compatibility mode. This is just using the WP_Query parameter, so you can pass whatever you want here to determine what should be added to the list.
Behind the scenes, Nicholas uses a lightweight router that can be extended using middleware mode, just like the way Express applications handle middleware. When the click page is routed, the system will run each middleware item and finally route the page. By default, the router does nothing ; however, it comes with some prefabricated middleware that allows you to assemble the router as needed.
A basic example is as follows:
<code>// 导入WordPress特定的中间件import { updateAdminBar, validateAdminPage, validateCompatibilityMode } from 'nicholas-wp/middlewares' // 导入通用中间件import { addRouteActions, handleClickMiddleware, setupRouter, validateMiddleware } from "nicholas-router"; // 按此顺序执行这些操作,当页面被路由时。 addRouteActions( // 首先,验证URL validateMiddleware, // 验证此页面不是管理页面validateAdminPage, // 验证此页面不需要兼容模式validateCompatibilityMode, // 然后,我们更新Alpine存储updateStore, // 如果启用,则可能获取评论fetchComments, // 更新历史记录updateHistory, // 可能更新管理栏updateAdminBar ) // 设置路由器。这也使用中间件模式。 setupRouter( // 为点击设置事件监听器handleClickMiddleware )</code>
From here, you can extend what happens when you route the page. Maybe you want to scan the page to highlight the code, or you want to change it The content of the tag is to match the page of the new route. Even a cache layer can be introduced. Whatever you need to do, add the required actions simply by using addRouteAction or setupRouter.
Here is my brief overview of some of the key components used to implement a near-headless approach. If you are interested in getting to know more, I recommend taking my course at WP Dev Academy. This course is a step-by-step guide to how to build a nearly headless WordPress website using modern tools. I also recommend checking out my near-headless boilerplate that can help you start your own project.
The above is the detailed content of How to Build a Nearly Headless WordPress Website. For more information, please follow other related articles on the PHP Chinese website!