I am using a WooCommerce plugin for WordPress. Now in a file page.php I am trying to get the current opened page id via $post->ID and the_id() but all I am getting is the product ID and not the current page ID. Probably because WooCommerce overwrites the loop ?
What can I do ?
It might be too late, but i was trying to get the same result as you and this below worked pretty well for me:
<?php
if(is_shop()){
$page_id = woocommerce_get_page_id('shop');
}else{
$page_id = $post->ID;
}
?>
Hope this will help you.
if you are trying to get the particular page id. Try with this.
if ( wc_get_page_id( 'name of page' ) != get_the_ID()):
This worked fine for me
global $post;$post->ID; or global $wp_query;$wp_query->post->ID; don't work with woocommerce. You can get all the id's of woocommerce page here
You can try this, inspired by woocommerce_product_archive_description
add_action('woocommerce_after_main_content', 'custom_name', 11, 2);
function custom_name() {
if ( is_post_type_archive( 'product' ) && 0 === absint( get_query_var( 'paged' ) ) ) :
global $post;
$shop_page = get_post( wc_get_page_id( 'shop' ) );
if ( $shop_page ) {
$post = $shop_page;
}
// your code here
endif;
}
$woo_pages_id = array(
//get_option( 'woocommerce_shop_page_id' ),
get_option( 'woocommerce_cart_page_id' ),
get_option( 'woocommerce_checkout_page_id' ),
//get_option( 'woocommerce_pay_page_id' ),
//get_option( 'woocommerce_thanks_page_id' ),
get_option( 'woocommerce_myaccount_page_id' ),
//get_option( 'woocommerce_edit_address_page_id' ),
//get_option( 'woocommerce_view_order_page_id' ),
get_option( 'woocommerce_terms_page_id' )
);
$current_page_id = get_the_ID();
if ( in_array($current_page_id, $woo_pages_id) ) :
get_template_part('content/woo', 'pages');
else :
get_template_part('content', 'page');
endif;
I'm using this for my page.php file.
put this line above your code or at starting of script.
global $post;
now you can use $post->ID;
thanks
Had the same problem found a solution here
The code I used on my shop page was:
<?php echo woocommerce_get_page_id('shop'); ?>
Basically replace the shop value with whatever woocommerce page you are trying to get.
More documentation on the function and some other helpful functions can be found here
Related
I am trying to make it so that the url.com/my-account or the shortcode [woocommerce_my_account] displays the orders instead of the dashboard that displays "Hello User (not user)?".
The only thing I have is for after logging in which redirects to the orders instead of the dashboard, but I then going to the /my-account still displays the dashboard which I don't want.
The closest code I found that does what I want is...
function woocommerce_orders() {
$user_id = get_current_user_id();
if ($user_id == 0) {
return do_shortcode('[woocommerce_my_account]');
}else{
ob_start();
wc_get_template( 'myaccount/my-orders.php', array(
'current_user' => get_user_by( 'id', $user_id),
'order_count' => $order_count
) );
return ob_get_clean();
}
}
add_shortcode('woocommerce_orders', 'woocommerce_orders');
However, if there are no orders placed then it comes out blank(doesn't display the "No order has been made yet." with shop button) and the my account nav-sidebar doesn't show up. Would I have to make a custom page-template for this to add in the woocommerce account nav-sidebar?
Edit: If I use the orders.php instead of my-orders.php then I am able to get the "No order has been made yet." But still no sidebar-nav
You could try the following code (that is not perfect as it removes the access to the dashboard):
add_action( 'woocommerce_account_content', 'remove_dashboard_account_default', 5 );
function remove_dashboard_account_default() {
remove_action( 'woocommerce_account_content', 'woocommerce_account_content', 10 );
add_action( 'woocommerce_account_content', 'custom_account_orders', 10 );
}
function custom_account_orders( $current_page ) {
global $wp;
if ( ! empty( $wp->query_vars ) ) {
foreach ( $wp->query_vars as $key => $value ) {
// Ignore pagename param.
if ( 'pagename' === $key ) {
continue;
}
if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
return;
}
}
}
$current_page = empty( $current_page ) ? 1 : absint( $current_page );
$customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array(
'customer' => get_current_user_id(),
'page' => $current_page,
'paginate' => true,
) ) );
wc_get_template(
'myaccount/orders.php',
array(
'current_page' => absint( $current_page ),
'customer_orders' => $customer_orders,
'has_orders' => 0 < $customer_orders->total,
)
);
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
There's a much easier way: simply catch WordPress's parse_request, check if the request is for my-account (or whatever your account page slug is) and perform a redirect:
function vnm_wc_redirect_account_dashboard( $wp ) {
if ( !is_admin() ) {
// Uncomment the following line if you want to see what the current request is
//die( $wp->request );
// The following will only match if it's the root Account page; all other endpoints will be left alone
if ( $wp->request === 'my-account' ) {
wp_redirect( site_url( '/my-account/orders/' ) );
exit;
}
}
}
add_action( 'parse_request', 'vnm_wc_redirect_account_dashboard', 10, 1 );
I used code of LoicTheAztec and another complementary snippet, which removes dashboard tab:
// Remove or rename my account page navigation links (removes downloads and dashboard).
add_filter ( 'woocommerce_account_menu_items', 'my_account_menu_order' );
function my_account_menu_order() {
$menuOrder = array(
'orders' => __( 'Orders', 'woocommerce' ),
// 'downloads' => __( 'Download', 'woocommerce' ),
'edit-address' => __( 'Addresses', 'woocommerce' ),
'edit-account' => __( 'Account details', 'woocommerce' ),
'customer-logout' => __( 'Logout', 'woocommerce' ),
// 'dashboard' => __( 'Dashboard', 'woocommerce' )
);
return $menuOrder;
}
I also created a snippet which causes orders tab to be highlighted by default. It's done through adding active class and then CSS opacity: 1 highlights it. Script will show only in account section to avoid bloat where it isn't needed:
// Make orders link highlighted by default in my account section.
add_action('wp_footer', 'taisho_dashboard_orders_highlight');
function taisho_dashboard_orders_highlight() {
if (!is_account_page()) return; // Account section only
global $wp;
$acc_url = get_permalink( get_option( 'woocommerce_myaccount_page_id' ));
$my_acc = rtrim( $acc_url , '/' );
$my_acc = explode( '/', $my_acc );
?>
<script type="text/javascript">
var dashboard_active = <?php echo $wp->request === end($my_acc) ?>;
jQuery(document).ready(function($) {
$('.woocommerce-MyAccount-navigation-link--orders').toggleClass('is-active', dashboard_active);
});
</script>
<?php
}
Using parse_request action:
add_action( 'parse_request', function ( $wp ) {
// Prevent the redirection, in the case,
// the user is not logged in (no login, no orders)
if (!is_user_logged_in()) return false;
if ( $wp->request === 'my-account' ) {
wp_redirect( home_url( '/my-account/orders/' ) );
exit;
}
}, 10, 1 );
As of today there's only one workaround to set another My Account tab as default and also preserve the "Dashboard" tab.
Let's say we want to default to the "Downloads" tab. We need to:
replace the “Dashboard” tab content with the “Downloads” tab content
rename the “Dashboard” tab to “Downloads”
hide the original “Downloads” tab as we already have it now
readd the “Dashboard” tab
This is a little complex to paste here so I'll cover point 1 only which is the most difficult one. The rest can be easily found on StackOverflow or this Business Bloomer tutorial as it's basic rename/remove/add My Account tabs work.
As per point 1, we need to overwrite the woocommerce_account_content() function which is responsible to display the "Dashboard" content by default in case we're on the My Account and there are no query vars or there is a non-empty query var called "pagename".
I will therefore remove the WooCommerce function, and add my version instead:
add_action( 'woocommerce_account_content', 'bbloomer_myaccount_replace_dashboard_content', 1 );
function bbloomer_myaccount_replace_dashboard_content() {
remove_action( 'woocommerce_account_content', 'woocommerce_account_content', 10 );
add_action( 'woocommerce_account_content', 'bbloomer_account_content' );
}
Now I go define my custom bbloomer_account_content() function, and I basically tell the system that:
if there is no query var or if there is and a query var called "pagename" is not empty, I echo my custom content (the "Downloads" tab content in my case"
otherwise, it means I am on an endpoint URL, and therefore I copy whatever was inside woocommerce_account_content() to return the tab content
Code:
function bbloomer_account_content() {
global $wp;
if ( empty( $query_vars = $wp->query_vars ) || ( ! empty( $query_vars ) && ! empty( $query_vars['pagename'] ) ) ) {
woocommerce_account_downloads();
} else {
foreach ( $wp->query_vars as $key => $value ) {
if ( 'pagename' === $key ) {
continue;
}
if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
return;
}
}
}
}
In this way, if I go to "example.com/my-account" I will see the "Downloads" tab content; if I switch tab and go to "Dashboard" or "Orders", I will see their original content instead.
Remember that this is only part 1 and therefore additional workaround is needed with parts 2, 3 and 4 to really make it work.
I have customised my Wordpress site design to use the featured image for posts quite excessively. This is why I need to require all post made by non-admins to require a set featured image.
How is this possible?
You need to hook the Publish Action in a custom PlugIn you write. Although this is to require a title, this should get you started, you just need to check if a featured image was assigned.
add_action( 'pre_post_update', 'bawdp_dont_publish' );
function bawdp_dont_publish()
{
global $post;
if ( strlen( $post->title ) < 10 ) {
wp_die( 'The title of your post have to be 10 or more !' );
}
}
Look at (has_post_thumbnail( $post->ID )) to determine if a post has a featured image.
Given Gary's example above, I've written the following to my functions.php file:
function featured_image_requirement() {
if(!has_post_thumbnail()) {
wp_die( 'You forgot to set the featured image. Click the back button on your browser and set it.' );
}
}
add_action( 'pre_post_update', 'featured_image_requirement' );
I'd much rather see this in a plugin as well - there's one called Mandatory Field but it doesn't work with scheduled posts. Both are not really eloquent solutions.
you can use a plugin
https://wordpress.org/plugins/require-featured-image/
or you can copy and paste below code in your wordpress theme functions.php file:
<?php
/**
* Require a featured image to be set before a post can be published.
*/
add_filter( 'wp_insert_post_data', function ( $data, $postarr ) {
$post_id = $postarr['ID'];
$post_status = $data['post_status'];
$original_post_status = $postarr['original_post_status'];
if ( $post_id && 'publish' === $post_status && 'publish' !== $original_post_status ) {
$post_type = get_post_type( $post_id );
if ( post_type_supports( $post_type, 'thumbnail' ) && ! has_post_thumbnail( $post_id ) ) {
$data['post_status'] = 'draft';
}
}
return $data;
}, 10, 2 );
add_action( 'admin_notices', function () {
$post = get_post();
if ( 'publish' !== get_post_status( $post->ID ) && ! has_post_thumbnail( $post->ID ) ) { ?>
<div id="message" class="error">
<p>
<strong><?php _e( 'Please set a Featured Image. This post cannot be published without one.' ); ?></strong>
</p>
</div>
<?php
}
} );
So, I'm developing a site for a client where the homepage is built like a one-page scroller, but I also need the functionality of additional pages outside of the single homepage. I've built a custom post type for these sections and used this code to display them on the homepage.
<?php query_posts( array('post_type'=>'homepage', 'posts_per_page' => 1000, 'orderby' => 'menu_order', 'order' => 'ASC') ); ?>
<?php if(have_posts()): while(have_posts()): the_post(); ?>
<?php
global $post;
$slug = $post->post_name;
locate_template(
array(
"template-$slug.php",
'template-main.php'
), true
);
?>
<?php endwhile; endif; ?>
So, as you can see, this is automatically pulling content and displaying it using page templates based on the post slug, however, I need to allow my client to display the content based on a page template chosen in a dropdown and I've used this code to create a dropdown UI that displays the page templates.
add_action( 'add_meta_boxes', 'add_custom_page_attributes_meta_box' );
function add_custom_page_attributes_meta_box(){
global $post;
if ( 'page' != $post->post_type && post_type_supports($post->post_type, 'page-attributes') ) {
add_meta_box( 'custompageparentdiv', __('Template'), 'custom_page_attributes_meta_box', NULL, 'side', 'core');
}
}
function custom_page_attributes_meta_box($post) {
$template = get_post_meta( $post->ID, '_wp_page_template', 1 ); ?>
<select name="page_template" id="page_template">
<?php $default_title = apply_filters( 'default_page_template_title', __( 'Default Template' ), 'meta-box' ); ?>
<option value="default"><?php echo esc_html( $default_title ); ?></option>
<?php page_template_dropdown($template); ?>
</select><?php
}
add_action( 'save_post', 'save_custom_page_attributes_meta_box' );
function save_custom_page_attributes_meta_box( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
if ( ! empty( $_POST['page_template'] ) && get_post_type( $post_id ) != 'page' ) {
update_post_meta( $post_id, '_wp_page_template', $_POST['page_template'] );
}
}
So, the problem I'm facing now is how to display all the custom posts in my main page according to the chosen page template.
Thanks so much!
J
Wordpress actually only uses _wp_page_template meta field for page type posts. If you want to change the template, you can use the filter single template. One thing I would recommend is you place good notes that you are using this in your theme/ plugin....
btw update cpt to your post-type
function load_cpt_template($single_template) {
global $post;
if ($post->post_type == 'cpt') {
$new_template = get_post_meta( $post->ID, '_wp_page_template', true );
// if a blank field or not valid do nothing, load default..
if( is_file($new_template) )
$single_template = $new_template;
}
return $single_template;
}
add_filter( 'single_template', 'load_cpt_template' );
EDIT : Even after making the Permalink Settings to Post name, http://domain.com/?paged=3 still works.
I have posts collection in my home page which has pagination. Let's say I have
domain.com
If my Permalink settings is in default which is Plain Format like
http://domain.com/?p=123
Then my pagination http://domain.com/?paged=3 will work.
How ever if I want my permalink settings to be in Post Name Format like
http://domain.com/sample-post/
Then my pagination in my home page will not work anymore. I tried inspect element in the link of pagination if set in post name permalink and it's
http://domain.com/page/23/
Then what happened is it will not go to page 23. It will always redirect to my home page
http://domain.com
I already tried this
https://wordpress.stackexchange.com/questions/134339/pagination-on-custom-post-type-not-working-if-permalinks-set-to-rewrite-url
Which I put this code in my functions.php
add_filter( 'redirect_canonical','custom_disable_redirect_canonical' );
function custom_disable_redirect_canonical( $redirect_url ){
if ( is_singular('your_custom_post_type') ) $redirect_url = false;
return $redirect_url;
}
And it didn't work.
Update I checked the functions.php and i see this
/* -----------------------------------------------------------------------------
Woo commerce
*/
if (in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' )))) { // check if we have woo commerce installed
// breadcrumb
add_filter( 'woocommerce_breadcrumb_defaults', 'td_woocommerce_breadcrumbs' );
function td_woocommerce_breadcrumbs() {
return array(
'delimiter' => ' <span class="td-sp td-sp-breadcrumb-arrow td-bread-sep"></span> ',
'wrap_before' => '<div class="entry-crumbs" itemprop="breadcrumb">',
'wrap_after' => '</div>',
'before' => '',
'after' => '',
'home' => _x( 'Home', 'breadcrumb', 'woocommerce' ),
);
}
// number of products to display on shop page
add_filter('loop_shop_per_page', create_function('$cols', 'return 8;'));
if (!function_exists('woocommerce_pagination')) {
// pagination
function woocommerce_pagination(){
echo td_page_generator::get_pagination();
}
}
if (!function_exists('woocommerce_output_related_products')) {
// number of related product
function woocommerce_output_related_products() {
woocommerce_related_products(4,4); // Display 4 products in rows of 4
}
}
}
/**
* Add prev and next links to a numbered link list - the pagination on single.
*/
function wp_link_pages_args_prevnext_add($args)
{
global $page, $numpages, $more, $pagenow;
if (!$args['next_or_number'] == 'next_and_number')
return $args; # exit early
$args['next_or_number'] = 'number'; # keep numbering for the main part
if (!$more)
return $args; # exit early
if($page-1) # there is a previous page
$args['before'] .= _wp_link_page($page-1)
. $args['link_before']. $args['previouspagelink'] . $args['link_after'] . '</a>'
;
if ($page<$numpages) # there is a next page
$args['after'] = _wp_link_page($page+1)
. $args['link_before'] . $args['nextpagelink'] . $args['link_after'] . '</a>'
. $args['after']
;
return $args;
}
add_filter('wp_link_pages_args', 'wp_link_pages_args_prevnext_add');
add_theme_support('woocommerce');
It doesn't have woo commerce plugin but It has that code. Hope it helps you find out whats going on?
Is is not possible to have a page name and a custom post type with the same name. If you do, the page url-slug of the page name and custom post type slug are the same and will cause a not found error.
If you are using WP_Query for retrieving posts then change your code to below
$paged = ( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1;
$args = array(
'posts_per_page' => 5,
'post_type' => 'post',
'paged' => $paged,
);
$the_query = new WP_Query( $args );
while ( $the_query->have_posts() ) : $the_query->the_post();
the_title();
echo '<br>';
endwhile;
$big = 999999999;
echo paginate_links( array(
'format' => '?paged=%#%',
'current' => max( 1, $paged ),
'total' => $the_query->max_num_pages
) );
Beside other mentioned scenarios, Make sure you do not have the slug of the template you are using the loop on similar to any of the post types exist in the theme. If a page slug is similar to the post type slug, the pagination will not work properly.
I have customised my Wordpress site design to use the featured image for posts quite excessively. This is why I need to require all post made by non-admins to require a set featured image.
How is this possible?
You need to hook the Publish Action in a custom PlugIn you write. Although this is to require a title, this should get you started, you just need to check if a featured image was assigned.
add_action( 'pre_post_update', 'bawdp_dont_publish' );
function bawdp_dont_publish()
{
global $post;
if ( strlen( $post->title ) < 10 ) {
wp_die( 'The title of your post have to be 10 or more !' );
}
}
Look at (has_post_thumbnail( $post->ID )) to determine if a post has a featured image.
Given Gary's example above, I've written the following to my functions.php file:
function featured_image_requirement() {
if(!has_post_thumbnail()) {
wp_die( 'You forgot to set the featured image. Click the back button on your browser and set it.' );
}
}
add_action( 'pre_post_update', 'featured_image_requirement' );
I'd much rather see this in a plugin as well - there's one called Mandatory Field but it doesn't work with scheduled posts. Both are not really eloquent solutions.
you can use a plugin
https://wordpress.org/plugins/require-featured-image/
or you can copy and paste below code in your wordpress theme functions.php file:
<?php
/**
* Require a featured image to be set before a post can be published.
*/
add_filter( 'wp_insert_post_data', function ( $data, $postarr ) {
$post_id = $postarr['ID'];
$post_status = $data['post_status'];
$original_post_status = $postarr['original_post_status'];
if ( $post_id && 'publish' === $post_status && 'publish' !== $original_post_status ) {
$post_type = get_post_type( $post_id );
if ( post_type_supports( $post_type, 'thumbnail' ) && ! has_post_thumbnail( $post_id ) ) {
$data['post_status'] = 'draft';
}
}
return $data;
}, 10, 2 );
add_action( 'admin_notices', function () {
$post = get_post();
if ( 'publish' !== get_post_status( $post->ID ) && ! has_post_thumbnail( $post->ID ) ) { ?>
<div id="message" class="error">
<p>
<strong><?php _e( 'Please set a Featured Image. This post cannot be published without one.' ); ?></strong>
</p>
</div>
<?php
}
} );