How to replicate a shortcode inside template - php

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

Related

how to display the upc in product page with opencart3?

I want to display the upc in product page with opencart 3. How do I do that?
I added the below code into my template file /catalog/view/theme/default/template/product/product.twig,but it doesn't work.
{% if upc %}
{{ upc }}
{% endif %}
Please do not forget to backup these files first.
You have to add upc as a variable to the controller first and then echo it in the template.
in order to do that:
first edit controller file:
/catalog/controller/product/product.php
and search for
$data['model'] = $product_info['model'];
after that add:
$data['upc'] = $product_info['upc'];
and save the file.
After that your code in template file that you mentioned will work.
ps: by this approach you lose these changes if you update opencart.A better approach would be to make an ocmod extension for it.

Dynamically grab latest post OctoberCMS Blog plugin

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.

Timber pagination with custom Query gives me 404

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 %}

WooCommerce: Single-product-postslug template not working?

First,I know wordpress won't allow you to use template for posts (WooCommerce's product page is built via post). So I look for the Template Hierarchy.
It says there:
single-{post-type}-{slug}.php (Since 4.4). First, WordPress looks for a template for the specific post.
For example, if post type is product and the post slug is dmc-12, WordPress would look for single-product-dmc-12.php.
single-{post-type}.php – If the post type is product, WordPress would look for single-product.php.
single.php – WordPress then falls back to single.php.
singular.php – Then it falls back to singular.php.
index.php – Finally, as mentioned above, WordPress ultimately falls back to index.php.
So I created a template and name it single-product-ccc (ccc is one of my product's slug name), but nothing happened, nothing was affected.
But by creating a template named single-product will affect all of the product pages.
Why is that happening?
I don't get it. Even a single-2313.php (2313 is one post's id) will overwrite the default single.php for that 2313 post.
Why single-product-slug is not working in the same way?
Thanks.
Let me first correct you at one point. You say: "WooCommerce's product page is built via post".
This is not correct. WooCommerce creates a new post type 'product'. You can see all custom posts types that WooCommerce creates here: https://docs.woocommerce.com/document/installed-taxonomies-post-types/
The 'product' post type uses the template single-product.php.
As you say, WordPress Template Hierarchy Docs say that you can create a template for a particular product:
single-{post-type}-{slug}.php (Since 4.4). First, WordPress looks for a template for the specific post. For example, if post type is product and the post slug is dmc-12, WordPress would look for single-product-dmc-12.php.
WooCommerce is a WordPress plugin and as so, it doesn't always follow WordPress rules strictly, and this is one of those cases. But you can use a filter to correct this very easily. In your theme's functions.php simply add:
add_filter( 'template_include', 'custom_single_product_template_include', 50, 1 );
function custom_single_product_template_include( $template ) {
if ( is_singular('product') && (get_the_ID()==30)) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-30.php';
}
return $template;
}
where get_the_ID() is the id of your Product. Now, you can create a new template as for example single-product-30.php
Try adding this in functions.php
function your_theme_add_woocommerce_support() {
add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'your_theme_add_woocommerce_support' );
and now onwards, you can use woocommerce/single-product.php for customisation

Yoast SEO | How to create custom variables

Was just wondering if there is a way to create a custom variable so that I can add my custom variable created in the Meta title of the page.
Yoast SEO has a list of variables predefined here.
It would be great if I could create a variable of my own. Is there any way to get this?
Thanks in advance!
You have two options for this.
Add filter for change exist variable.
Add your new custom variable.
If you want to change exist variable, you can do it like this:
// define the wpseo_replacements callback
function filter_wpseo_replacements( $replacements ) {
if( isset( $replacements['%%page%%'] ) ){
$replacements['%%page%%'] = 'Page x of y';
}
return $replacements;
};
// Add filter
add_filter( 'wpseo_replacements', 'filter_wpseo_replacements', 10, 1 );
And if do you want to add custom variable you can do it like this:
// define the custom replacement callback
function get_myname() {
return 'My name is Moses';
}
// define the action for register yoast_variable replacments
function register_custom_yoast_variables() {
wpseo_register_var_replacement( '%%myname%%', 'get_myname', 'advanced', 'some help text' );
}
// Add action
add_action('wpseo_register_extra_replacements', 'register_custom_yoast_variables');
I hope I was helpful to you.
There is a way, but as far as I know, you must get a Premium account in Yoast Seo. One of the most important functions of both Yoast SEO and Yoast SEO Premium is the possibility to add title templates and meta description templates to the homepage, all (custom) post types, all (custom) taxonomies and other pages.
Note: Template variables can also be used on individual posts, pages and taxonomies.
Setting up / changing your templates
You can change your title & meta templates by going to the admin of your WordPress installation and clicking SEO → Titles & Metas.
Log in to your WordPress website. When you're logged in, you will be in your 'Dashboard'. On the left-hand side, you will see a menu. In that menu, click on 'SEO'.
The 'SEO' settings will expand providing you additional options. Click on 'Titles & Metas'.
Under each tab, you can use these variables to create templates for various pages within your site.
You can use the variables from the partial list below to create your own templates for the titles and meta-descriptions. The full list of variables is listed on the HELP tab of the plugin. Just go to SEO → Titles & Metas and click the help tab in the top right.
For more about that and see many images of the process, please visit this page: http://kb.yoast.com/article/146-yoast-wordpress-seo-titles-metas-template-variables

Categories