Change the default global edit link that lists my CustomPostType (edit.php?post_type=CPT), to use a plugin page link instead - wordpress

I'm working on a plugin (with a https://wppb.me/ plugin boilerplate base, if relevant).
I defined my custom post type, with the editor options I want, that I can edit with the default /wp-admin/post.php?post={id}&action=edit
The listing of those CPT is done on my plugin pages only (no specific menu for the CPT) and I want to keep it that way.
Problem:
I'd like to change the base edit link of this post type when no ID is specified
( eg : /wp-admin/edit.php?post_type=CPT ) to be the URL of my plugin
( eg : /wp-admin/admin.php?page=myplugin )
This, mostly because in Gutenberg Editor Fullscreen, the top left wordpress logo links to the /wp-admin/edit.php?post_type=CPT that I don't wont to use nor show. I'd like this link to be a page of my plugin (here, it would be the homepage of my plugin)
I tried with a filter on get_edit_post_link when there is no ID provided, but it doesn't seem to be the correct way to fix my problem.
Any tips or help to get me in the right direction in my research are welcome !

I found one of the possible solutions. After entering the site, you must redirect the user.
function wp_custom_update_meta_cache_filter() {
global $pagenow, $typenow;
if ( $pagenow == 'edit.php' && $typenow == 'CPT' ) {
wp_safe_redirect();
die();
}
}
add_action( 'admin_init', 'wp_custom_update_meta_cache_filter' );
Based in (233 line):
https://github.com/dipolukarov/wordpress/blob/master/wp-content/plugins/woocommerce/admin/woocommerce-admin-init.php

Related

Endpoints not working on WooCommerce checkout page

I developing a custom theme. I have an issue on checkout page. When I click on 'Place order' button the URL of checkout page changing from http://localhost/sitename/checkout to look like http://localhost/sitename/checkout/order-received/390/?key=wc_order_DvIkeeaIUoNFI if payment-method is 'Cash on delivery' or http://localhost/sitename/checkout/order-pay/391/?key=wc_order_2TbWibkoOZcxz&order=391 if I choose Internet acquiring payment-method.
But on that pages displayed content of checkout page. I think that endpoints don't work.
Here is what I did to fix that issue:
Checked endpoints in WooCommerce -> Settings -> Advanced
Created new checkout page and deleted old
Checked Chrome DevTools Console for JS errors
Turned off all plugins except for WooCommerce. Issue still exists.
Checked it on another test-site with Storefront theme. Everything works.
Checked all default Woocommerce hooks in my custom checkout templates. There are available.
Create web.configfile in site's directory with code which provides on https://woocommerce.com/document/woocommerce-endpoints-2-1/
Trying to redirect with this code:
<?php
add_action( 'template_redirect', 'woo_custom_redirect_after_purchase' );
function woo_custom_redirect_after_purchase() {
global $wp;
if ( is_checkout() && !empty( $wp->query_vars['order-received'] ) ) {
wp_redirect( home_url('/thank-you') );
exit;
}
if ( is_checkout() && !empty( $wp->query_vars['order-pay'] ) ) {
wp_redirect( 'https://secure.wayforpay.com/pay' );
exit;
}
}
?>
As for me it's bad solution. Because if payment-method is 'Cash on delivery' on thank you page it is not possible to get order data, and if method is 'Internet acquiring' I need to get and transfer order data to acquiring system, but I have a plugin which should do it without my participation. And plugin working on another test-site.
This issue is very popular among junior Wordpress-developers, but there is few information about solving this problem.
I think that endpoints works incorrect, but I don't know how to fix it.
I will be very grateful if you share your own experience in solving the problem or tell me what to look for.
Updated
In addition I compared requests and responds in Chrome->DevTools->Network between site with Storefront theme and my site. They are the same, but on my site the redirect is not happening.
I fixed it.
Main issue consist in that my woocommerce doesn't do shortcodes from Console->Pages, so I activated checkout template via page-checkout.php where I get template part form-checkout.php (get_template_part( 'woocommerce/checkout/form-checkout' );).
To fix a bug I replaced this string with echo do_shortcode(['woocommerce_checkout']);.
Very simple solution that I spent almost 3 days searching for, but even better I learned how wordpress works

How to show WooCommerce Categories on 'shop' page instead of products?

I have seen this question and answer. That does not work.
Setup
I am running:
WordPress 5.4.1
WooCommerce 4.1.1
I have a custom theme that overrides some of the WooCommerce templates by placing my own templates in: themes/my_theme/woocommerce/template-name.php
I have established that the shop page (homepage) uses the template archive-product.php. I have copied the this from plugins/woocommerce/templates/archive-product.php into my theme and made some minor HTML changes which work perfectly. There are no functional changes in my theme's copy, just some HTML.
The problem
I want the homepage to only show the store categories, as thumbnails. There is an option to set the shop page to show categories instead of products:
Appearance > Customize > WooCommerce > Catalogue
Shop page display has been set to Show Categories
However the shop homepage seems to ignore this setting entirely, and it still shows the products. It seems surprising that WooCommerce's own template does not honour this setting!
How do I find this setting in the template and then show the categories (as thumbnails) on the shop homepage?
Is there an equivalent to woocommerce_product_loop() for looping categories?
As a side note, the Storefront theme does honour the setting but Storefront does not have the template archive-product.php. Storefront seems to be highly abstracted and after much debugging of it / trying to take it apart I have so far not worked out which template file it is using for the shop page.
My theme is already in production and I just want to make an update so that the homepage shows the categories instead of going directly into the products list.
I found a workable solution. The WooCommerce default templates don't support the setting to show categories on the Shop page.
However using a shortcode with do_shortcode(), and a condition this can be achieved as follows:
if (is_shop()) {
echo do_shortcode('[product_categories hide_empty="0"]');
} else {
woocommerce_product_loop_start();
if ( wc_get_loop_prop( 'total' ) ) {
while ( have_posts() ) {
the_post();
/**
* Hook: woocommerce_shop_loop.
*/
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
}
woocommerce_product_loop_end();
}
Still:
I would like to know how to pick up the 'show categories' customisation setting shown in the question, so my theme responds to that.
Is there a better way than using do_shortcode(), this feels like a bit of a hack

How do I remove Woocommerce sidebar from cart, checkout and single product pages?

Like many people that start using woocommerce for the first time I need to know how to customise it. In my particular situation I want to remove the sidebar from the Cart, Checkout and single product pages. My sidebar is defined and called from sidebar.php using the code below:
<?php dynamic_sidebar('global-sidebar'); ?>
I have tried for a long time to find an answer that works but I can't seem to find the correct code or solution. Perhaps asking the question myself will work. By the way I really appreciate the answers in the other articles and how-to's but they don't work for me.
Before I go any further I am using Bootstrap (latest version as of 2014) to style my Wordpress website. Not sure if that matters but maybe it does somehow.
Can someone please tell me how I find and then tell Woocommerce not to display any kind of sidebar on the Cart, Checkout and Single Product pages?
p.s.
The website can be found here > wp.wunderful.co.uk (staging site for a client website project)
Go to "Cart" page from dashboard pages, from "Page Attribute Section" -> "Templates" choose "Full Width" this will give you a page without sidebar.
In theory, something like the following ought to work, but I haven't tested it. (To be added to your theme's functions.php)
function so_25700650_remove_sidebar(){
if( is_checkout() || is_cart() || is_product() ){
remove_action( 'woocommerce_sidebar', 'woocommerce_get_sidebar', 10 );
}
}
add_action('woocommerce_before_main_content', 'so_25700650_remove_sidebar' );
If you look at the Woo templates you will see
<?php
/**
* woocommerce_sidebar hook
*
* #hooked woocommerce_get_sidebar - 10
*/
do_action( 'woocommerce_sidebar' );
?>
This is Woo saying: "Display the sidebar here". But it is adding the woocommerce_get_sidebar function to the woocommerce_sidebar hook... which is convenient because it allows you to unhook that function like I've shown above. Finally, I am using Woo's conditional logic to only unhook the function from its action on the pages you requested.
I'm running my function on the woocommerce_before_main_content hook, which I think should work assuming your theme hasn't removed that hook. If so, then you could probably use wp_head or something that is guaranteed to be there, though then you'd probably want to check that the is_checkout(), etc functions exist or risk breaking your theme should you ever deactivate WooCommerce. As I have it, i should only run on WooCommerce-specific pages and so checking if the WooCommerce functions are defined is probably overkill.
Important Note:
This assumes the default theme or a theme that isn't running its own custom sidebar functions. If your theme is doing something else you will need to investigates its particular functions and templates.
What you should do is to create a files called woocomemrce.php in your theme if it doesn't already exists. Then you should look at your page template files for full width and for page with sidebar to see how they are structured and see where they differ.
Then copy the contents of one the files into woocommerce.php and replace the loop with woocommerce_content(), see this page for details.
Lastly see where the different page templates differ and then use if-statements in the places where they differ.
if( is_post_type_archive( 'product' ) ) :
//Content to display in the list view (i.e. with sidebar)
else :
//Content to display all other views (i.e. without sidebar)
endif;
.woocommerce-cart .sidebar {
display: none;
}
.woocommerce-cart .content-area {
width: 100%;
}
add this in custom/style.css.
From
https://wordpress.org/support/topic/remove-sidebar-for-woocommerce-cart-and-checkout-pages/
On your theme, likely subtheme, function.php
add_action('wp_head', 'hide_sidebar' ); function hide_sidebar(){ if(is_cart() || is_checkout()){ ?>
<style type="text/css">
#secondary {
display: none;
}
</style>
<?php
}
To remove sidebar from the Cart, Checkout and single product pages you want to use action hook in function.php file -
add_action('woocommerce_before_main_content', 'remove_sidebar' );
function remove_sidebar()
{
if( is_checkout() || is_cart() || is_product()) {
remove_action( 'woocommerce_sidebar', 'woocommerce_get_sidebar', 10);
}
}
Here you can get WooCommerce Action and Filter Hook
-https://docs.woothemes.com/wc-apidocs/hook-docs.html

How to map an arbitrary URL to a function in a Wordpress plugin

I'm trying to create a Wordpress plugin that redirects visitors of example.com/redirect/XXX to a different page based on the value of XXX. I think I know how to do the redirect logic, but I don't know how to make sure that my Wordpress plugin function will be called when a visitor goes to example.com/redirect. Right now I just get a 404. There are other solutions that involved changing the .htaccess file, but I want this to function as a standalone plugin. Thanks!
When I need this kind of things i just create a common page with template as the "plugin", a page with all the functions that I need.
For example, if i need a shopping cart, I just create a cart.php as:
<?php
/*
Template Name: Cart
*/
// functions here
?>
And I go to my wp-admin and create a page with Cart as its template.
Depending on what exactly you want to do which is quite vague ( when you say page you actually mean page ? post ? cpt ? and when you say plugin functions - what are they ? and do you use permalinks ?)
.. but under some conditions you could use wp conditionals .
example ( from codex )
is_singular( 'foo' )
// Returns true if the post_type is "foo". execute plugin hook
is_singular( array( 'foo', 'bar', 'baz' ) )
// Returns true if the post_type is "foo", "bar", or "baz".
// See also the Custom Post Types book.
or if you aim at filtering you can always hook to pre_get_post with is_main_query() or any other conditional //

Wordpress How to Check whether it is POST or PAGE

How to check if an article is a post or a page in WordPress?
You can use the is_page() and is_single() functions.
You can also use get_post_type() function.
if (get_post_type() === 'post') {
// POST
}
if (get_post_type() === 'page') {
// PAGE
}
If you're looping through a collection of posts/pages (say, on a search results page), then is_single() and is_page() won't be of any use. In this situation, you could grab the global $post object (of type WP_Post) and examine the $post->post_type property. Possible values include 'post' and 'page'.
is_singular() returns true for a single post, page or attachment
You mean that is_single() will return true if it is a post ? (not a page), am I right,
I like that, I think you wrong, because I have a plugin show some text on only post, I'm using is_single() but It also show on pages.
Please advice.
Thanks
if you want y¡to know the page that list the posts , and you are using the posts page option in the configuration, You should use is_home().
It's for developer, if you are not a developer you can also check current page type. You have to just inspect particular page and see body tag. If theme is build with basic WordPress rules then body tag have classes related to page or single page. These classes may b included the post type, template name, file name, page id and many more.

Resources