I'm using Recent products shortcode, [recent_products per_page="4" columns="2"]
and would like to have pagination, because I'm displaying products on homepage - and currently only 4 products are being displayed. Is there a way to add pagination?
I have imported dummy data, so there are 45 products.
Use [recent_products limit="12" columns="4" paginate="true"] This shortcode limit 12 means maximum 12 post on a page.
more info woocommerce doc
You could consider a plugin: WP-PageNavi. In order to use it with Woocommerce, simply install and configure the plugin, then add the following code to your theme's functions.php:
remove_action('woocommerce_pagination', 'woocommerce_pagination', 10);
function woocommerce_pagination() {
wp_pagenavi();
}
add_action( 'woocommerce_pagination', 'woocommerce_pagination', 10);
Source: Mark van der Putten's blog, comments ommitted.
Also, you could ask this question on the dedicated StackExchange Wordpress site.
Referencing from this github gist https://gist.github.com/klihelp/7810337 Including the following code into your child-theme functions.php after installing this plugin: https://wordpress.org/plugins/prime-strategy-page-navi/
<?php
/**
* This code shows pagination for WooCommerce shortcodes when it's embeded on single pages.
* Include into functions.php.
*/
if ( ! is_admin() ) {
// ---------------------- FRONTPAGE -------------------
if ( defined('WC_VERSION') ) {
// ---------------------- WooCommerce active -------------------
/**
* Set Pagination for shortcodes custom loop on single-pages.
* #uses $woocommerce_loop;
*/
add_action( 'pre_get_posts', 'kli_wc_pre_get_posts_query' );
function kli_wc_pre_get_posts_query( $query ) {
global $woocommerce_loop;
// Get paged from main query only
// ! frontpage missing the post_type
if ( is_main_query() && ( $query->query['post_type'] == 'product' ) || ! isset( $query->query['post_type'] ) ){
if ( isset($query->query['paged']) ){
$woocommerce_loop['paged'] = $query->query['paged'];
}
}
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
return;
}
$query->is_paged = true;
$query->query['paged'] = $woocommerce_loop['paged'];
$query->query_vars['paged'] = $woocommerce_loop['paged'];
}
/** Prepare Pagination data for shortcodes on pages
* #uses $woocommerce_loop;
*/
add_action( 'loop_end', 'kli_query_loop_end' );
function kli_query_loop_end( $query ) {
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
return;
}
// Cache data for pagination
global $woocommerce_loop;
$woocommerce_loop['pagination']['paged'] = $woocommerce_loop['paged'];
$woocommerce_loop['pagination']['found_posts'] = $query->found_posts;
$woocommerce_loop['pagination']['max_num_pages'] = $query->max_num_pages;
$woocommerce_loop['pagination']['post_count'] = $query->post_count;
$woocommerce_loop['pagination']['current_post'] = $query->current_post;
}
/**
* Pagination for shortcodes on single-pages
* #uses $woocommerce_loop;
*/
add_action( 'woocommerce_after_template_part', 'kli_wc_shortcode_pagination' );
function kli_wc_shortcode_pagination( $template_name ) {
if ( ! ( $template_name === 'loop/loop-end.php' && is_page() ) ){
return;
}
global $wp_query, $woocommerce_loop;
if ( ! isset( $woocommerce_loop['pagination'] ) ){
return;
}
$wp_query->query_vars['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->query['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->max_num_pages = $woocommerce_loop['pagination']['max_num_pages'];
$wp_query->found_posts = $woocommerce_loop['pagination']['found_posts'];
$wp_query->post_count = $woocommerce_loop['pagination']['post_count'];
$wp_query->current_post = $woocommerce_loop['pagination']['current_post'];
// Custom pagination function or default woocommerce_pagination()
kli_woocommerce_pagination();
}
/**
* Custom pagination for WooCommerce instead the default woocommerce_pagination()
* #uses plugin Prime Strategy Page Navi, but added is_singular() on #line16
*/
remove_action('woocommerce_after_shop_loop', 'woocommerce_pagination', 10);
add_action( 'woocommerce_after_shop_loop', 'kli_woocommerce_pagination', 10);
function kli_woocommerce_pagination() {
wp_pagenavi();
}
}// END WOOCOMMERCE
}// END FRONTPAGE
Use [recent_products limit="12" columns="4" paginate="true"]. This shortcode limit 12 means maximum 12 post on a page. more info woocommerce doc
Related
I wish redirect my terms template to a page with the save slug (to allow the client to custom the page and use a template model for this page), this is my code
function redirect_archive_term() {
$categories = get_terms( array('taxonomy' => 'chapters') );
foreach($categories as $category) {
if( is_post_type_archive( $category->slug ) ) { // like chapter-1, chapter-2 ...
wp_redirect( home_url( '/'.$category->slug ), 301 );
exit();
}
}
}
add_action( 'template_redirect', 'redirect_archive_term' );
this is doesn't work because of the condition I think, there a way to target them ?
Thanks for the help :)
Should be pretty straight forward. The following is untested.
Function has to fire before the header is deployed, thus the use of the wp hook.
is_tax() can fire on search or archive page, we need to filter that out, thus ! is_search() && ! is_archive().
We get the current term from get_term() and we redirect through wp_safe_redirect().
<?php
/**
* Redirect term page to the corresponding custom slug page.
*
* #see https://stackoverflow.com/questions/71266569/redirect-custom-taxonomy-terms-archive-to-page
*
* #since 1.0.0
*
* #param void
* #return void
*/
add_action( 'wp', 'wpso_71266569' ); //hook into wp's init action hook
if ( ! function_exists( 'wpso_71266569' ) ) {
function wpso_71266569() {
//Let's make sure we're on a taxonomy "chapters" page:
//Either taxonomy-{taxonomy}.php or taxonomy-{taxonomy}-{term}.php.
if ( ! is_search() && ! is_archive() && is_tax( 'chapters' ) ) {
$term = get_term( get_queried_object_id() ); //Retrieve the current term slug.
wp_safe_redirect( home_url( trailingslashit( $term->slug ) ) ); //eg: Redirect to https://example.com/term_slug/.
};
};
};
I have a home page and shop page. I don't want to set my home page to shop page.
Home page is full of custom content and widgets, and right before this content I would like to have list of products with same pagination as on shop page.
This means I could not use shortcodes to display products as default shortcodes do not support pagination.
Have gone through all the docs and tried possible ways. But it always breaks something.
Any advice will appreciated.
Thx.
P.S. While you reading this I'm still trying to find solution, so I might post something soon :)
Finally found awesome solution right here.
I'm using shortcode [product_category per_page="4" category="category-slug"]
To make pagination alive, you need to activate this pagination.
Here is the exact code snippet that need to be pasted into the theme's functions.php:
if ( defined('WC_VERSION') ) {
// ---------------------- WooCommerce active -------------------
/**
* Set Pagination for shortcodes custom loop on single-pages.
* #uses $woocommerce_loop;
*/
add_action( 'pre_get_posts', 'kli_wc_pre_get_posts_query' );
function kli_wc_pre_get_posts_query( $query ) {
global $woocommerce_loop;
// Get paged from main query only
// ! frontpage missing the post_type
if ( is_main_query() && ( $query->query['post_type'] == 'product' ) || ! isset( $query->query['post_type'] ) ){
if ( isset($query->query['paged']) ){
$woocommerce_loop['paged'] = $query->query['paged'];
}
}
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
return;
}
$query->is_paged = true;
$query->query['paged'] = $woocommerce_loop['paged'];
$query->query_vars['paged'] = $woocommerce_loop['paged'];
}
/** Prepare Pagination data for shortcodes on pages
* #uses $woocommerce_loop;
*/
add_action( 'loop_end', 'kli_query_loop_end' );
function kli_query_loop_end( $query ) {
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
return;
}
// Cache data for pagination
global $woocommerce_loop;
$woocommerce_loop['pagination']['paged'] = $woocommerce_loop['paged'];
$woocommerce_loop['pagination']['found_posts'] = $query->found_posts;
$woocommerce_loop['pagination']['max_num_pages'] = $query->max_num_pages;
$woocommerce_loop['pagination']['post_count'] = $query->post_count;
$woocommerce_loop['pagination']['current_post'] = $query->current_post;
}
/**
* Pagination for shortcodes on single-pages
* #uses $woocommerce_loop;
*/
add_action( 'woocommerce_after_template_part', 'kli_wc_shortcode_pagination' );
function kli_wc_shortcode_pagination( $template_name ) {
if ( ! ( $template_name === 'loop/loop-end.php' && is_page() ) ){
return;
}
global $wp_query, $woocommerce_loop;
if ( ! isset( $woocommerce_loop['pagination'] ) ){
return;
}
$wp_query->query_vars['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->query['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->max_num_pages = $woocommerce_loop['pagination']['max_num_pages'];
$wp_query->found_posts = $woocommerce_loop['pagination']['found_posts'];
$wp_query->post_count = $woocommerce_loop['pagination']['post_count'];
$wp_query->current_post = $woocommerce_loop['pagination']['current_post'];
// Custom pagination function or default woocommerce_pagination()
kli_woocommerce_pagination();
}
/**
* Custom pagination for WooCommerce instead the default woocommerce_pagination()
* #uses plugin Prime Strategy Page Navi, but added is_singular() on #line16
*/
remove_action('woocommerce_after_shop_loop', 'woocommerce_pagination', 10);
add_action( 'woocommerce_after_shop_loop', 'kli_woocommerce_pagination', 10);
function kli_woocommerce_pagination() {
woocommerce_pagination();
}
}// END WOOCOMMERCE
Nice way to go for this try. The next thing is to make pagination ajax based without page reloading...
I have one wordpress/woocommerce site. When user cart amount is over 500 i must have free shipping in cart subtotal. Right now i have setup flat rate 25 and free shipping if amount is more then 500.
I google it from help and add some code into functions.php but still have same problem.
function hide_all_shipping_when_free_is_available( $available_methods ) {
if( isset( $available_methods['free_shipping'] ) ) :
// Get Free Shipping array into a new array
$freeshipping = array();
$freeshipping = $available_methods['free_shipping'];
// Empty the $available_methods array
unset( $available_methods );
// Add Free Shipping back into $avaialble_methods
$available_methods = array();
$available_methods['free_shipping'] = $freeshipping;
endif;
return $available_methods;
}
i use wordpress with woocommerce 2.3.8 on Oxygen theme.
Best regards
You're using the old method, you need to use this new one I think.
Copied from WooThemes website:
add_filter( 'woocommerce_package_rates','hide_shipping_when_free_is_available', 10, 2 );
function hide_shipping_when_free_is_available( $rates, $package ) {
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) ) {
// To unset a single rate/method, do the following. This example unsets flat_rate shipping
unset( $rates['flat_rate'] );
// To unset all methods except for free_shipping, do the following
$free_shipping = $rates['free_shipping'];
$rates = array();
$rates['free_shipping'] = $free_shipping;
}
return $rates;
}
I am using the Yoast SEO plugin in WordPress and wanted to know if there was a way to make it only visible to one specific user in the db or in the functions.php file? Not a role, an actual user.
I tried an universal solution to simply add "plugin-name" and disable it, but failed.
But, to show WPSEO only to a specific user (ID equals 2), the following works:
add_action( 'plugins_loaded', 'seo_so_25654837' );
function seo_so_25654837()
{
if ( '2' == get_current_user_id() )
return;
remove_action( 'plugins_loaded', 'wpseo_admin_init', 15 );
}
Don't add the code to functions.php, use it as a normal plugin.
The following is also needed to remove the SEO menu from the admin bar:
add_action( 'wp_before_admin_bar_render', 'bar_so_25654837' );
function bar_so_25654837()
{
if ( '2' == get_current_user_id() )
return;
global $wp_admin_bar;
$nodes = $wp_admin_bar->get_nodes();
foreach( $nodes as $node )
{
if( !$node->parent )
{
if( 'wpseo-menu' === $node->id )
$wp_admin_bar->remove_menu( $node->id );
}
}
}
You can hook to pre_current_active_plugins to remove elements from the table before it is displayed. Using get_current_user_id() within the function will let you selectively hide a plugin.
function hide_plugins_by_user( $all_plugins=false ) {
global $wp_list_table;
// if the current user ID is not 1, hide it.
if ( 1 != get_current_user_id() ){
// the active plugins from the table
$plugins = $wp_list_table->items;
// loop through them
foreach ( $plugins as $key => $val ) {
// use the dir + filename of the plugin to hide
if ( $key == 'plugindir/plugin.php' ) {
unset( $wp_list_table->items[$key] );
}
}
}
}
add_action( 'pre_current_active_plugins', 'hide_plugins_by_user' );
This code is working fine (Credits goes to Hislop):
// Returns true if user has specific role
function check_user_role( $role, $user_id = null ) {
if ( is_numeric( $user_id ) )
$user = get_userdata( $user_id );
else
$user = wp_get_current_user();
if ( empty( $user ) )
return false;
return in_array( $role, (array) $user->roles );
}
// Disable WordPress SEO meta box for all roles other than administrator and seo
function wpse_init(){
if( !(check_user_role('seo') || check_user_role('administrator')) ){
// Remove page analysis columns from post lists, also SEO status on post editor
add_filter('wpseo_use_page_analysis', '__return_false');
// Remove Yoast meta boxes
add_action('add_meta_boxes', 'disable_seo_metabox', 100000);
}
}
add_action('init', 'wpse_init');
function disable_seo_metabox(){
remove_meta_box('wpseo_meta', 'post', 'normal');
remove_meta_box('wpseo_meta', 'page', 'normal');
}
Just place it in the functions.php file.
To disable the Yoast for all the users and enable it for just for few or specific, just add the following piece of code to your function.php file.
function remove_wpseo(){
/* if you want to keep it enabled for user with id 2 */
if ( '2' == get_current_user_id() ) {
return;
}
global $wpseo_front;
if(defined($wpseo_front)){
remove_action('wp_head',array($wpseo_front,'head'),1);
}
else {
$wp_thing = WPSEO_Frontend::get_instance();
remove_action('wp_head',array($wp_thing,'head'),1);
}
}
add_action('template_redirect','remove_wpseo');
Reference: https://makersbyte.com/disable-yoast-seo-plugin-specific-page/
I know how to create a custom template for a specific page. However I would like to create a template for a specific custom post type. Is that possible and if true how can I do that?
If I create a new template it will show in admin only when I'm adding a page, but when I'm adding a new post type I don't have the option to select a certain template.
Problem resolved:
/*
Show the list of available custom templates templates in the Custom Post Type admin section
*/
/**
* Post_type
*/
define( 'MY_THEME_POST_TYPE', 'cases' );
/**
* Load the page template for any post object
* having the appropriate meta key set.
*/
add_action( 'template_redirect', 'mytheme_template_redirect' );
function mytheme_template_redirect() {
global $wp_query;
$id = (int) $wp_query->get_queried_object_id();
$template = get_post_meta( $id, '_wp_page_template', true );
if ( $template && 'default' !== $template ) {
$file = STYLESHEETPATH . '/' . $template;
if( is_file( $file ) ) {
require_once $file;
exit;
}
}
}
/**
* Process the Meta Box
* #todo Permissions check.
* #todo Filter input.
* #todo Nonces.
*/
add_action( 'save_post', 'mytheme_process_resource_template' );
function mytheme_process_resource_template() {
global $post;
/* Sanitize $_POST array. */
$clean_id = ( isset( $_POST['ID'] ) ) ? intval( $_POST['ID'] ) : 0;
if ( !empty( $_POST['page_template'] ) && MY_THEME_POST_TYPE == $post->post_type ) {
$page_templates = get_page_templates();
if ( 'default' != $page_template && !in_array( $_POST['page_template'], $page_templates ) ) {
if ( $wp_error )
return new WP_Error('invalid_page_template', __('The page template is invalid.'));
else
return 0;
}
update_post_meta( $clean_id, '_wp_page_template', $_POST['page_template'] );
}
}
/**
* Registers the Meta Box
* #uses mytheme_page_attributes_meta_box()
*/
add_action( 'admin_init', 'mytheme_register_meta_boxes', 10 );
function mytheme_register_meta_boxes() {
add_meta_box(
'mytheme_post_type_template',
'Template',
'mytheme_page_attributes_meta_box',
MY_THEME_POST_TYPE,
'side',
'low'
);
}
/**
* Creates the Meta Box
*/
function mytheme_page_attributes_meta_box() {
global $post;
$post_type_object = get_post_type_object($post->post_type);
if ( 0 != count( get_page_templates() ) ) {
$template = get_post_meta( $post->ID, '_wp_page_template', true );
?>
<p><strong><?php _e('Template') ?></strong></p>
<label class="screen-reader-text" for="page_template"><?php _e('Page Template') ?></label><select name="page_template" id="page_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php page_template_dropdown( $template ); ?>
</select>
<?php
}
}
Create page that is called:
single-{cpt-slug}.php e.g. single-product.php
It will be used when showing a page of a custom post type. i.e. when someone goes to http://example.com/product/awesome-shoes/