What is the best approach in Sage 9 themes to use a custom page template and display archive of custom post type there?
I could create a WP_Query and some custom pagination (managing in a custom controller for the created page template) but was wondering if it’s perhaps better to just somehow modify the query via filters so that the main loop on a custom page template already acts and displays archive posts with pagination without adding many a lot of perhaps unnecessary custom code.
The above would alter your main loop so that you don’t have to create a new WP_Query in your template part. If you need more assistance with this hook then stackexchange covers a lot of similar questions
Alternatively you could leverage the Controller to make your data available in your template files, however the controller approach wouldn’t be as efficient as the pre_get_posts approach. More chatter about Controller usage here:
What’s your custom template for? If its primary purpose is to display a list of your custom posts, the best approach may be to just add an archive-myposttype.blade.php template for this and let WordPress do the querying, etc., for you.
Otherwise, I would almost certainly go the controller route; I don’t think pre_get_posts would be a good option here. If you’re making an independent page, so to speak, and not just a customized archive for the CPT, the page will have its own data that the query fetches. If you use pre_get_posts to hijack the query that is happening when your page is loaded to get your list of posts, it will no longer contain your page’s data. Instead, leave the page’s query alone and use the controller to fetch the posts you need and pass them to your template.
thanks for your answers; some more information if that helps:
It’s for displaying a list of custom posts, yeah, but in a custom way (added filtering etc.). Default archive would be enough with it’s functionalities (since it provides the loop with pagination that I need anyways), but that means you gotta use the archive URL that is given to that specific custom post type, for example /faq. I know I can do a rewrite to get archive page on something like /support/faq (here a list of FAQs), but that’s not a solution for multi-language pages (need to be a ble to translate all slugs).
Also, I want to be able to move the FAQ page to a different parent (change hierarchy) and still show the archive as I’ll prepare it.
Yep that makes perfect sense, I read “on a custom template” in your question title and assumed you’d like the freedom of having a dynamic archive type page for URLs etc.
Using pre_get_posts is likely to be the best solution to allow for dynamic URLs… I don’t think the word hijack is accurate with pre_get_posts, it makes it seem as though using pre_get_posts is categorically wrong. In fact when used correctly you can alter the main query perfectly fine so long as you’re mindful of pagination and deal with any offsets. Maybe pre_get_posts is still recovering from the bad press due to incorrect usage in publicly available themes and plugins all those years ago.
The above would get your custom archive page working.
You may also need to access the existing page data. i.e. the page template has content which you need to pull in besides the custom posts. If this is the case you can use the returned post id outside of the loop to grab that data in your template file - this data is available and not destroyed. Due to WPs caching and object creation this will be handled in a performant manner in most cases.
@while($faqs_query->have_posts()) @php($faqs_query->the_post())
// custom code to display each custom post info
@endwhile
// this is a simple "paginate_links" wrapper
@include('components/pagination', [
'total' => $faqs_query->max_num_pages,
'current' => max( 1, get_query_var( 'paged' ) ),
])
{{ wp_reset_postdata() }}
This works as expected with not much work and it’s pretty clean I think.
It shows my custom post (‘faq’) archive under any page I assign this template to, for example /support/faq/.
But there is one last thing I’d like to make this perfect, which is similar to what @craigpearson already mentioned: rewrites for certain FAQ urls. But not for each faq, since they won’t have separate pages, but for custom taxonomy that is assigned to it.
I’m displaying custom taxonomy (lets call it ‘FAQ categories’) terms on the side and by clicking them I’d like the URL to change to whatever the current page is (support/faq) + term name.
So for example: /support/faq/faq_category_1 would display the same archive page but filtered to show posts for this term only.
I can easily solve this by adding GET param to URL instead of doing rewrites, but it’s much nicer with actual URLs.
Any thoughts on how to accomplish this perhaps not an easy task?
@mmirus I do know about rewriting but that didn’t seem as nice when I thought about it, perhaps I need to rethink how I approach things when things get too custom.
On the other hand, @alwaysblank’s Cortex solution might just be what I needed? I do need to dig a bit deeper before actually using it on production though. Is there an example how to properly implement some basic multilingual (using WPML if that’s important) custom routes with Sage? Otherwise I’ll
probably over-engineer things since I’m quite new to Sage