I am kinda a newbie at Wordpress.
I've looked a lot on StackOverflow for a solution for this problem but none worked for me.
I'm using Timber and ACF.
Here's the situation: I've made 4 custom post_type ( News, Products, Services and Places ). I've created a custom page for the news. (page-news.twig )
In my page.php file I've added a custom query like this:
global $paged;
if (!isset($paged) || !$paged) {
$paged = 1;
}
$context = Timber::get_context();
$post = new TimberPost();
$context['post'] = $post;
$args = array(
'post_type' => 'news',
'posts_per_page' => 3,
'paged' => $paged,
'page' => $paged
);
$context['news'] = new Timber\PostQuery($args);
So I've set a maximum of posts for page, which is 3, and In my .twig file:
{% for single_news in news %}
{% include['news.twig', single_news] %}
{% endfor %}
{% if news.pagination.prev %}
Prev
{% endif %}
{% if news.pagination.next %}
Next
{% endif %}
When I go to the news page, there are 3 posts per page ( correct ) and it displays me the Next anchor which is correct.
The problem is that the link brings me to /news/page/2 that doesn't exists and gives me 404 error. I've tried many solutions like the pre_get_posts and none worked for me.
Pagination only works on archive pages, but not on singular pages. See The WordPress Template Hierarchy for what counts as an archive page.
This means that you can’t use page.php as your template file for displaying your news posts. You have two possibilities here:
You can use archive.php, or even archive-news.php if your Custom Post Type for news is named news.
If you’d use the default post type post for your news section, you could select the page where you want to display your posts archive. The template file to display your posts archive would then be home.php.
If you go for the first option, you need to make sure that when you register your post type (either through register_post_type() or a plugin), you set the public option to true and that you set has_archive to true as well.
The problem with archive pages is that now you can’t use some editing functionalities that you normally have with pages. For an archive, you can’t set a title or add content with the editor like you’re used for pages. But if you use ACF, you can set up an options page where you add a select for your «Page for News». Name it page_for_news and then, in your template file, you can select the proper post that Timber should use on the archive page with
$post = new Timber\Post( get_field( 'page_for_news', 'option' ) );
This method practically replicates option 2 for Custom Post Types.
Also, a hint about your news post include in Twig:
{% for single_news in news %}
{% include['news.twig', single_news] %}
{% endfor %}
If you do this, then Twig will try to find a news.twig template as well as a template named after single_news. But single_news is not a string here, but an instance of Timber\Post. So that doesn’t help you. You can use the following instead:
{% for single_news in news %}
{% include 'news.twig' %}
{% endfor %}
Related
In wordpress functions.php file I have a shortcode that allows me to display the order ID when I'm on the view-order.php page. The shortcode works fine.
What I am trying to do is find a more comfortable alternative to this. So I would like to take advantage of the Twig template, so I'm doing some testing. I'm actually viewing the order ID, but it stays the same for every order I decide to view.
Example:
if I view the order 001, the ID 001 is shown (correct)
if I view the order 002, the ID 001 is shown (incorrect)
With the shortcode this does not happen, I can correctly display the ID of each order. Can anyone tell me where I'm doing wrong?
I've already done the same thing with my-orders page and my-downloads page, it worked fine, but for some reason it's not working with view-order.php page.
I appreciate any response, thanks.
add_shortcode( 'view_order_id' , 'view_order_00' );
function view_order_00(){
$order_id = absint( get_query_var('view-order') );
$order = new WC_Order( $order_id );
return $order->get_id();
}
{% set post = system.get.order_id|php('get_post') %}
{% set order = post.ID|php('wc_get_order') %}
{% for item in order.get_items %}
{% for download in order.get_downloadable_items %}
<div>{{post.ID}}</div>
{%endfor%}
{% endfor %}
I am using a third party plugin called e-addons, this offers many widgets for elementor, including Twig Template.
I contacted plugin support and they told me that I would have to pass the order ID in $ _GET to fix the problem. Furthermore, all this must be done in a dedicated elementor page and not in the view-order.php template as I was doing initially.
So here is a brief explanation of what I did step by step to fix the problem. I hope it will be useful to anyone who has had the same difficulties as me.
1. I created a new page with elementor titled test page. The
2. I copied the permalink of the newly created page (test-page) and put it in a filter in the functions.php file, here it is below.
// When you click on view order, this filter allows you to redirect from view-order (original woocommerce endpoint) to a custom page created with elementor.
function filter_woocommerce_get_endpoint_url( $url, $endpoint, $value, $permalink ) {
// Specific endpoint: If in the advanced settings of woocommerce you have changed the endpoint view order, then below you have to replace view-order with the one you have chosen in the advanced settings wi WC
if ( $endpoint === 'view-order' ) {
// New URL: change test-page with permalink of the page you created earlier. The /?order_id= part should not be removed.
$url = $permalink . 'test-page/?order_id=' . $value;
}
return $url;
}
add_filter( 'woocommerce_get_endpoint_url', 'filter_woocommerce_get_endpoint_url', 10, 4 );
3. After setting the filter with the permalink we need to modify the new page with elementor. Once in the editor I selected the e-Addons Posts Query widget and dragged it to the page area.
Step 3 opens here, follow these steps to configure the widget correctly, only change what is mentioned below:
Go to the Query Tab of the query posts widget
Query
In query type select Post Type
In options> post type select order
in post status select Any
Query Filter
in "By" select Meta Key
in Mtakey Filters add new and modify as follows
in Post Field custom meta key select _customer_user
in Value Type select Numeric
in Compare operator select "="
in Post Field Value select User Field
If you do everything correctly in step 3, the user will be able to view the orders, otherwise if you do something wrong you get nothing.
Here ends step 3.
4. Then go to the first tab of the widget entitled Content. Here you have to go to the menu item titled Post Items, and this is where I played with the Twig template. So the code I originally posted in my question now works.
{% set post = system.get.order_id|php('get_post') %}
{% set order = post.ID|php('wc_get_order') %}
{% for item in order.get_items %}
{% for download in order.get_downloadable_items %}
<div>{{post.ID}}</div>
{%endfor%}
{% endfor %}
Now, when I am on the order history page and click on view order I am redirected correctly to the specific order page which for example is mywebsite.com/account/test-page?order_id=xxxxxx
I asked this question in the October forums but 12 hours later the post still says "unapproved" and I don't believe it's visible. Here's a copy-paste:
What I want to do is grab the latest blog post and display it on the homepage of the website. I can do it currently with my own post partial and the posts variable injected by the blogPosts component like so:
[blogPosts]
pageNumber = "{{ :page }}"
postsPerPage = 10
noPostsMessage = "No posts found"
sortOrder = "published_at desc"
categoryPage = "blog/category"
postPage = "blog/post"
==
{% partial 'site/blogpost' post=posts|last %}
However, I'd like to do this with the default blogpost component that comes with the plugin, but the only way to pass the post to the component seems to be by using the slug in the url, which doesn't really work for the homepage. How can I achieve this?
It is possible to use blogPost component but fetching last post slug and pass to it seems not good practice
what you do is you can use [blogPosts] component and set proper setting there to get latest/last blog
to make it possible
Posts per page : 1 [ as we need only last latest post ]
Post Order : Published(desc) [ you can change as you need ]
now just use proper markup to render it use default or just override to customise it.
Note : It will return list of post but in list there will be only 1 post as demanded so for custom markup just take care of that.
if any doubt please comment.
So, as with most things when it comes to development... RTFM.
All the info I needed was in the Components section of the October CMS docs, and of course I was only looking in the plugin docs. What I ended up doing was overriding the default component partial with my own and then passing the slug to the component. My original reason for wanting to use the default partial was that my custom partial wasn't rendering images, but the default would. I just needed to steal the line <p>{{ post.content_html|raw }}</p> to get that to work.
[blogPost]
==
...
{% component 'blogPost' slug=posts|last.slug %}
Additional info: With the above solution your template pulls all blog posts in the database, which means if you have a lot of posts this could (and most likely will) affect performance. Turns out October templates have a PHP section. The proper thing to do is to remove the blogPosts component and grab the latest post Model like so:
[blogPost]
==
<?
use RainLab\Blog\Models\Post;
function onStart()
{
$this['latestPost'] = Post::latest()->first();
}
?>
==
{% component 'blogPost' slug=latestPost.slug %}
Note: The blogPost component injects a post variable which will override a post variable defined in the PHP section. This is way the variable is labeled latestPost.
I am using Timber for a WordPress project. I am trying to get my custom 404 error page twig template to display on 404 errors. Currently, my 404 errors are showing a blank screen. However, when I go to the route: /404 my template displays. I am assuming there is either something wrong with how I am routing or I am missing some key logic in 404.php.
How can I get my twig template to display for my 404 errors?
Route code in functions.php:
Routes::map('/404', function($params){
Routes::load('routes/404.php', null, $params, 404);
});
404.php:
<?php
$context = Timber::get_context();
$post = new TimberPost();
$context['page'] = $post;
global $wp;
$url = home_url($wp->request);
$context['url'] = preg_replace('#^https?://#', '', rtrim($url, '/'));
$context['global'] = get_fields('options');
Timber::render('views/pages/404.twig', $context);
404.twig:
{% extends "layouts/layout.twig" %}
{% block content %}
<div class="row row-is-centered">
<div class="col ns-col-is-8 lead-6 txt-center">
<h1 class="txt-size-5">Our apologies, we couldn't find {{url}}</h1>
</div>
</div>
{% endblock %}
You shouldn't have to setup any custom routing in order for WordPress to pick up the 404 page. Here is the WP Codex on 404 Pages
Also if you are using the Timber starter theme, this works out of the box by default. Here are the files that come with the theme, I just tested this on a Timber project I am currently working on and I haven't done anything to setup a custom 404 page. I just have what the Timber starter theme comes with by default:
404.php
<?php
/**
* The template for displaying 404 pages (Not Found)
*
* Methods for TimberHelper can be found in the /functions sub-directory
*
* #package WordPress
* #subpackage Timber
* #since Timber 0.1
*/
$context = Timber::get_context();
Timber::render( '404.twig', $context );
404.twig
{% extends "base.twig" %}
{% block content %}
Sorry, we couldn't find what you're looking for.
{% endblock %}
It also looks like routes are now deprecated: https://timber.github.io/docs/upgrade-guides/1.0/#routes
I am not sure how far along you are in your project, but you might want to try to upgrade to the latest version of Timber and use their starter theme to get going. They provide a lot of templates that work out of the box and make things a lot easier. However, you should be careful upgrading if you are pretty far along in your project because I am sure there will be breaking changes like the routes feature for instance. The page referenced above provides some good information on whether or not you should upgrade and how to do so.
Hope that helps.
I'm in the process of building a site in October CMS that uses a slash page. The splash page is only supposed to show to non cookied users the first time that they visit the site. I am controlling this part via a component in a plugin called splash. Here is my onRun() function:
public function onRun()
{
$key = 'shownsplash';
if(!Session::has($key) || !Cookie::get($key))
{
$this->page['showsplash'] = true;
Cookie::queue('shownsplash',true);
Session::put($key,true);
$resp = NULL;
}
}
In my main page layout called 'default' I want to conditionally load the splash page template called 'splash' using the following:
{% if showsplash %}
{{ loadpage('splash') }}
{% else %}
Regular page template
{% endif %}
Except that I'm not sure how to load a page conditionally. One additional requirement is that the splash page takes the url http://www.example.com and not any subsequent pages. Can anyone point out how to do this?
in octobercms cms/page are hit by url , the url set in the config section and are bound to a layout. so for me page are more 'routing' object than html content holder.
In fact partials ARE html content holder
So if i had to do the same thing as you mean i would use partial and page.
a page with url="/" and two partials, one for the regular page and one for the splash.
bind your plugin component to the page not the layout
{% if showsplash %}
{% partial 'home/splash.htm' %}
{% else %}
{% partial 'home/regular.html' %}
{% endif %}
I think partial are exactly what to use in this kind of conditional stuff.
generaly think of
layout as website structuration
page mainly for routing
partial for html content
I have this include file with following code. I assume I can used wordpress is_single() to twig template file. When I tried to accessing the detail page of a wordpress post this display the word Nothing.
Even though I have a post name foo post and I did also create a rev_slider named foo post.
{% if wp.is_single('foo post') %}
{{ wp.do_shortcode('[rev_slider foo post]')|raw }}
{% else %}
Nothing
{% endif %}
Am I doing this correctly?
Your code is correct, but just be sure you have the right post title or the right post name is wp.is_single()