In our last post, we talked about embracing new technologies without having to completely abandon existing infrastructure. For us, finding ways to embrace fast, flexible, and modern frontends while not having to abandon longstanding and well-loved WordPress content management structures for some of our clients has been an enjoyable endeavor.
All little on page templates.
In many ways, creating page templates for Astro projects is very similar to WordPress, as much as a PHP template can be the same as an Astro template that is.
But there are some key differences to consider...
In WordPress, we have a file structure within the theme that maps to the content getting called. Your files and file structure aren't dictating the structure of your site, they are just responding to a route that has been created and called by the application, WordPress. So, for example, if we have a taxonomy we've created for "topics", the application will create an archive for topics. Us creating a file called archive-topic.php doesn't tell the system to create that route, only that when that route is called use that template. If that file didn't exist, the system would look for a generic archive.php template and render the content with it.
With Astro, you have a little more control (some would read that as responsibility) in creating the structure of the site. We can create folders, dynamic routes, nesting, etc. to tell the application what the structure of the site will be and give it templates when building the content we define. At every file where content will be created, we add a getStaticPaths method that tells the application what content we want to build with that template and to generate those pages.
And now for the archives.
So, when we use an application like Astro to create a frontend with our WordPress content, we have to do a little more work to create the term archives that are automatically created within WordPress.
- Create the file structure for routing the paths for the archives. When we add files here, we can take advantage of Astro's structure for creating dynamic routes as well as paginating them. (pages > topic > [topic].astro & pages > topic > [topic] > [page].astro).
- Within our [topic].astro file, we'll create a typical getStaticPaths build out where we call all of the possible slugs (using a collection) for that route. However, rather than building out a page of content associated with that topic here (which you very well could within this template), I like to rewrite with the first page of our paginated archive response.
return Astro.rewrite(`/topic/${topic}/1`);
- I would then utilize our [topic] > [page].astro to build out the paginated archives for each topic that we have. For this, we'll pass both the topic and the collection of possible results (posts) into our getStaticPaths method on that file. We check the posts to see if they are associated with the current, dynamic content and then pass it to the return if it is.
- At this point, we have all of the posts but we haven't separated them into chunks to display on paginated results. To do this, we use the paginate function on the return to chunk them and have Astro create the associated numbered pages.
Here is a breakdown of our paginated archive paths using this approach.
export async function getStaticPaths({ paginate }) {
const topics = await getCollection("topics");
const resources = await getCollection("resources");
return topics.flatMap((topic) => {
const filteredPosts = resources.filter((post) => {
const topicNodes = Array.isArray(post.data.topics?.nodes)
? post.data.topic.nodes
: [];
const slugs = topicNodes
.map((topic) => topic?.slug || "")
.filter(Boolean);
return slugs.includes(topic.data.slug);
});
return paginate(filteredPosts, {
params: { topic: topic.data.slug },
props: {
topic: topic.data.slug,
name: topic.data.name,
},
pageSize: 16,
});
});
}
Curious about other templates when switching to a headless approach? Drop us a line and we'd be happy to chat.