Commit realizado el 12:13:52 08-04-2024
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* The WooCommerce module - admin side functionality.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
use RankMath\KB;
|
||||
use RankMath\Admin\Admin_Helper;
|
||||
use RankMath\Module\Base;
|
||||
use RankMath\Traits\Hooker;
|
||||
use RankMath\Helpers\Arr;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Admin class.
|
||||
*/
|
||||
class Admin extends Base {
|
||||
|
||||
use Hooker;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$directory = dirname( __FILE__ );
|
||||
$this->config(
|
||||
[
|
||||
'id' => 'woocommerce',
|
||||
'directory' => $directory,
|
||||
]
|
||||
);
|
||||
parent::__construct();
|
||||
|
||||
// Permalink Manager.
|
||||
$this->filter( 'rank_math/settings/general', 'add_general_settings' );
|
||||
$this->filter( 'rank_math/flush_fields', 'flush_fields' );
|
||||
|
||||
$this->action( 'rank_math/admin/editor_scripts', 'enqueue' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue script to analyze product's short description.
|
||||
*/
|
||||
public function enqueue() {
|
||||
$screen = get_current_screen();
|
||||
if ( ! Admin_Helper::is_post_edit() || 'product' !== $screen->post_type || ! $this->do_filter( 'woocommerce/analyze_short_description', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_script( 'rank-math-description-analysis', rank_math()->plugin_url() . 'includes/modules/woocommerce/assets/js/woocommerce.js', [ 'rank-math-editor' ], rank_math()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add module settings into general optional panel.
|
||||
*
|
||||
* @param array $tabs Array of option panel tabs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_general_settings( $tabs ) {
|
||||
Arr::insert(
|
||||
$tabs,
|
||||
[
|
||||
'woocommerce' => [
|
||||
'icon' => 'rm-icon rm-icon-cart',
|
||||
'title' => esc_html__( 'WooCommerce', 'rank-math' ),
|
||||
/* translators: Link to kb article */
|
||||
'desc' => sprintf( esc_html__( 'Choose how you want Rank Math to handle your WooCommerce SEO. %s.', 'rank-math' ), '<a href="' . KB::get( 'woocommerce-settings', 'Options Panel WooCommerce Tab' ) . '" target="_blank">' . esc_html__( 'Learn more', 'rank-math' ) . '</a>' ),
|
||||
'file' => $this->directory . '/views/options-general.php',
|
||||
],
|
||||
],
|
||||
7
|
||||
);
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fields after updation of which we need to flush rewrite rules.
|
||||
*
|
||||
* @param array $fields Fields to flush rewrite rules on.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function flush_fields( $fields ) {
|
||||
$fields[] = 'wc_remove_product_base';
|
||||
$fields[] = 'wc_remove_category_base';
|
||||
$fields[] = 'wc_remove_category_parent_slugs';
|
||||
|
||||
return $fields;
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* Add Open Graph data for the WooCommerce module.
|
||||
*
|
||||
* @since 1.0.32
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
use RankMath\OpenGraph\Image as OpenGraph_Image;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC Opengraph class.
|
||||
*/
|
||||
class Opengraph extends Sitemap {
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*/
|
||||
public function opengraph() {
|
||||
$this->filter( 'language_attributes', 'og_product_namespace', 11 );
|
||||
$this->filter( 'rank_math/opengraph/desc', 'og_desc_product_taxonomy' );
|
||||
$this->action( 'rank_math/opengraph/facebook', 'og_enhancement', 50 );
|
||||
$this->action( 'rank_math/opengraph/facebook/add_additional_images', 'set_opengraph_image' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the OpenGraph namespace.
|
||||
*
|
||||
* @param string $namespace The original namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function og_product_namespace( $namespace ) {
|
||||
if ( is_singular( 'product' ) ) {
|
||||
$namespace = preg_replace( '/prefix="([^"]+)"/', 'prefix="$1 product: https://ogp.me/ns/product#"', $namespace );
|
||||
}
|
||||
|
||||
return $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the OpenGraph description is put out.
|
||||
*
|
||||
* @param string $desc The current description, will be overwritten if we're on a product page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function og_desc_product_taxonomy( $desc ) {
|
||||
if ( is_product_taxonomy() ) {
|
||||
$term_desc = term_description();
|
||||
if ( ! empty( $term_desc ) ) {
|
||||
$desc = wp_strip_all_tags( $term_desc, true );
|
||||
$desc = strip_shortcodes( $desc );
|
||||
}
|
||||
}
|
||||
|
||||
return $desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the other product images to the OpenGraph output.
|
||||
*
|
||||
* @param OpenGraph $opengraph The current opengraph network object.
|
||||
*/
|
||||
public function og_enhancement( $opengraph ) {
|
||||
$product = $this->get_product();
|
||||
if ( ! is_object( $product ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$brand = WooCommerce::get_brands( get_the_ID() );
|
||||
if ( ! empty( $brand ) ) {
|
||||
$opengraph->tag( 'product:brand', $brand );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow developers to prevent the output of the price in the OpenGraph tags.
|
||||
*
|
||||
* @param bool unsigned Defaults to true.
|
||||
*/
|
||||
if ( $this->do_filter( 'woocommerce/og_price', ! $product->is_type( 'variable' ) ) ) {
|
||||
$opengraph->tag( 'product:price:amount', $product->get_price() );
|
||||
$opengraph->tag( 'product:price:currency', get_woocommerce_currency() );
|
||||
}
|
||||
|
||||
if ( $product->is_in_stock() ) {
|
||||
$opengraph->tag( 'product:availability', 'instock' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the opengraph images.
|
||||
*
|
||||
* @param OpenGraph_Image $opengraph_image The OpenGraph image to use.
|
||||
*/
|
||||
public function set_opengraph_image( OpenGraph_Image $opengraph_image ) {
|
||||
if ( ! function_exists( 'is_product_category' ) || is_product_category() ) {
|
||||
global $wp_query;
|
||||
$cat = $wp_query->get_queried_object();
|
||||
$thumbnail_id = get_term_meta( $cat->term_id, 'thumbnail_id', true );
|
||||
$opengraph_image->add_image_by_id( $thumbnail_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Passing a truthy value to the filter will effectively short-circuit the process of adding gallery images.
|
||||
*
|
||||
* @param bool $return Short-circuit return value. Either false or true.
|
||||
*/
|
||||
if ( ! $this->do_filter( 'woocommerce/opengraph/add_gallery_images', false ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$product = $this->get_product();
|
||||
if ( ! is_object( $product ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->set_image_ids( $product, $opengraph_image );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set images for the given product.
|
||||
*
|
||||
* @param WC_Product $product The product to get the image ids for.
|
||||
* @param OpenGraph_Image $opengraph_image The OpenGraph image to use.
|
||||
*/
|
||||
protected function set_image_ids( $product, $opengraph_image ) {
|
||||
$img_ids = method_exists( $product, 'get_gallery_image_ids' ) ?
|
||||
$product->get_gallery_image_ids() : $product->get_gallery_attachment_ids();
|
||||
|
||||
if ( ! is_array( $img_ids ) || empty( $img_ids ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $img_ids as $img_id ) {
|
||||
$opengraph_image->add_image_by_id( $img_id );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
/**
|
||||
* The product permalink watcher class.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Traits\Hooker;
|
||||
use RankMath\Helpers\Sitepress;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Helpers\Param;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Permalink_Watcher class.
|
||||
*/
|
||||
class Permalink_Watcher {
|
||||
|
||||
use Hooker;
|
||||
|
||||
/**
|
||||
* Hold product base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $product_base;
|
||||
|
||||
/**
|
||||
* Hold product categories.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $categories;
|
||||
|
||||
/**
|
||||
* Remove product base.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $remove_product_base;
|
||||
|
||||
/**
|
||||
* Remove category base.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $remove_category_base;
|
||||
|
||||
/**
|
||||
* Remove parent slugs.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $remove_parent_slugs;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->remove_product_base = Helper::get_settings( 'general.wc_remove_product_base' );
|
||||
$this->remove_category_base = Helper::get_settings( 'general.wc_remove_category_base' );
|
||||
$this->remove_parent_slugs = Helper::get_settings( 'general.wc_remove_category_parent_slugs' );
|
||||
|
||||
if ( $this->remove_product_base && ! (bool) Param::get( 'elementor-preview' ) ) {
|
||||
$this->filter( 'post_type_link', 'post_type_link', 1, 2 );
|
||||
}
|
||||
|
||||
if ( $this->remove_category_base || $this->remove_parent_slugs ) {
|
||||
$this->action( 'created_product_cat', 'flush_rules' );
|
||||
$this->action( 'delete_product_cat', 'flush_rules' );
|
||||
$this->action( 'edited_product_cat', 'flush_rules' );
|
||||
|
||||
$this->filter( 'term_link', 'term_link', 0, 3 );
|
||||
$this->filter( 'rewrite_rules_array', 'add_rewrite_rules', 99 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush rewrite rules (soft flush).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flush_rules() {
|
||||
flush_rewrite_rules( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace product permalink according to settings.
|
||||
*
|
||||
* @param string $permalink The existing permalink URL.
|
||||
* @param WP_Post $post WP_Post object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function post_type_link( $permalink, $post ) {
|
||||
if ( $this->can_change_link( 'product', $post->post_type ) ) {
|
||||
return $permalink;
|
||||
}
|
||||
|
||||
return str_replace( $this->get_product_base(), '/', $permalink );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace category permalink according to settings.
|
||||
*
|
||||
* @param string $link Term link URL.
|
||||
* @param object $term Term object.
|
||||
* @param string $taxonomy Taxonomy slug.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function term_link( $link, $term, $taxonomy ) {
|
||||
if ( $this->can_change_link( 'product_cat', $taxonomy ) ) {
|
||||
return $link;
|
||||
}
|
||||
|
||||
$permalink_structure = wc_get_permalink_structure();
|
||||
$category_base = trailingslashit( $permalink_structure['category_rewrite_slug'] );
|
||||
$is_language_switcher = ( class_exists( 'Sitepress' ) && strpos( $link, 'lang=' ) );
|
||||
|
||||
if ( $this->remove_category_base ) {
|
||||
$link = str_replace( $category_base, '', $link );
|
||||
$category_base = '';
|
||||
}
|
||||
|
||||
if ( $this->remove_parent_slugs && ! $is_language_switcher ) {
|
||||
$link = home_url( user_trailingslashit( $category_base . $term->slug ) );
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add rewrite rules.
|
||||
*
|
||||
* @param array $rules The compiled array of rewrite rules.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_rewrite_rules( $rules ) {
|
||||
global $wp_rewrite;
|
||||
|
||||
wp_cache_flush();
|
||||
|
||||
/**
|
||||
* Remove WPML filters while getting terms, to get all languages
|
||||
*/
|
||||
Sitepress::get()->remove_term_filters();
|
||||
|
||||
$feed = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';
|
||||
|
||||
$permalink_structure = wc_get_permalink_structure();
|
||||
$category_base = $this->remove_category_base ? '' : $permalink_structure['category_rewrite_slug'];
|
||||
$use_parent_slug = Str::contains( '%product_cat%', $permalink_structure['product_rewrite_slug'] );
|
||||
|
||||
$product_rules = [];
|
||||
$category_rules = [];
|
||||
foreach ( $this->get_categories() as $category ) {
|
||||
$cat_path = $this->get_category_fullpath( $category );
|
||||
$cat_slug = $category_base . ( $this->remove_parent_slugs ? $category['slug'] : $cat_path );
|
||||
|
||||
$category_rules[ "{$cat_slug}/?\$" ] = 'index.php?product_cat=' . $category['slug'];
|
||||
$category_rules[ "{$cat_slug}/embed/?\$" ] = 'index.php?product_cat=' . $category['slug'] . '&embed=true';
|
||||
$category_rules[ "{$cat_slug}/{$wp_rewrite->feed_base}/{$feed}/?\$" ] = 'index.php?product_cat=' . $category['slug'] . '&feed=$matches[1]';
|
||||
$category_rules[ "{$cat_slug}/{$feed}/?\$" ] = 'index.php?product_cat=' . $category['slug'] . '&feed=$matches[1]';
|
||||
$category_rules[ "{$cat_slug}/{$wp_rewrite->pagination_base}/?([0-9]{1,})/?\$" ] = 'index.php?product_cat=' . $category['slug'] . '&paged=$matches[1]';
|
||||
|
||||
if ( $this->remove_product_base && $use_parent_slug ) {
|
||||
$product_rules[ $cat_path . '/([^/]+)/?$' ] = 'index.php?product=$matches[1]';
|
||||
$product_rules[ $cat_path . '/([^/]+)/' . $wp_rewrite->comments_pagination_base . '-([0-9]{1,})/?$' ] = 'index.php?product=$matches[1]&cpage=$matches[2]';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register WPML filters back
|
||||
*/
|
||||
Sitepress::get()->restore_term_filters();
|
||||
|
||||
$rules = empty( $rules ) ? [] : $rules;
|
||||
return $category_rules + $product_rules + $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns categories array.
|
||||
*
|
||||
* ['category id' => ['slug' => 'category slug', 'parent' => 'parent category id']]
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_categories() {
|
||||
if ( is_null( $this->categories ) ) {
|
||||
$categories = get_categories(
|
||||
[
|
||||
'taxonomy' => 'product_cat',
|
||||
'hide_empty' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$slugs = [];
|
||||
foreach ( $categories as $category ) {
|
||||
$slugs[ $category->term_id ] = [
|
||||
'parent' => $category->parent,
|
||||
'slug' => $category->slug,
|
||||
];
|
||||
}
|
||||
|
||||
$this->categories = $slugs;
|
||||
}
|
||||
|
||||
return $this->categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively builds category full path.
|
||||
*
|
||||
* @param object $category Term object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_category_fullpath( $category ) {
|
||||
$categories = $this->get_categories();
|
||||
$parent = $category['parent'];
|
||||
|
||||
if ( $parent > 0 && array_key_exists( $parent, $categories ) ) {
|
||||
return $this->get_category_fullpath( $categories[ $parent ] ) . '/' . $category['slug'];
|
||||
}
|
||||
|
||||
return $category['slug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product base.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_product_base() {
|
||||
if ( is_null( $this->product_base ) ) {
|
||||
$permalink_structure = wc_get_permalink_structure();
|
||||
$this->product_base = $permalink_structure['product_rewrite_slug'];
|
||||
if ( strpos( $this->product_base, '%product_cat%' ) !== false ) {
|
||||
$this->product_base = str_replace( '%product_cat%', '', $this->product_base );
|
||||
}
|
||||
$this->product_base = '/' . trim( $this->product_base, '/' ) . '/';
|
||||
}
|
||||
|
||||
return $this->product_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the link can be changed or not.
|
||||
*
|
||||
* @param string $check Check string.
|
||||
* @param string $against Against this.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function can_change_link( $check, $against ) {
|
||||
return $check !== $against || ! get_option( 'permalink_structure' );
|
||||
}
|
||||
}
|
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/**
|
||||
* The WooCommerce module's product redirection features.
|
||||
*
|
||||
* @since 1.0.32
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Traits\Hooker;
|
||||
use RankMath\Helpers\Sitepress;
|
||||
use RankMath\Helpers\Param;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Redirections\Redirection;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WooCommerce class.
|
||||
*/
|
||||
class Product_Redirection {
|
||||
|
||||
use Hooker;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( Helper::is_module_active( 'redirections' ) ) {
|
||||
$this->filter( 'rank_math/redirection/pre_search', 'pre_redirection', 10, 3 );
|
||||
return;
|
||||
}
|
||||
|
||||
$this->action( 'wp', 'redirect' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-filter the redirection.
|
||||
*
|
||||
* @param string $check Check.
|
||||
* @param string $uri Current URL.
|
||||
* @param string $full_uri Full URL.
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public function pre_redirection( $check, $uri, $full_uri ) {
|
||||
if ( $new_link = $this->get_redirection_url() ) { // phpcs:ignore
|
||||
return [
|
||||
'url_to' => $new_link,
|
||||
'header_code' => 301,
|
||||
];
|
||||
}
|
||||
|
||||
return $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect product with base to the new link.
|
||||
*/
|
||||
public function redirect() {
|
||||
if ( $link = $this->get_redirection_url() ) { // phpcs:ignore
|
||||
Helper::redirect( $link, 301 );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Product URL.
|
||||
*
|
||||
* @return string Modified URL
|
||||
*/
|
||||
private function get_redirection_url() {
|
||||
if ( ! $this->can_redirect() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$url = $this->get_source_url();
|
||||
$is_product = is_product();
|
||||
$permalink_structure = wc_get_permalink_structure();
|
||||
$base = $is_product ? $permalink_structure['product_base'] : $permalink_structure['category_base'];
|
||||
|
||||
$base = explode( '/', ltrim( $base, '/' ) );
|
||||
$new_link = $url;
|
||||
|
||||
// Early Bail if new_link length is less then the base.
|
||||
if ( count( explode( '/', $new_link ) ) <= count( $base ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// On Single product page redirect base with shop and product.
|
||||
if ( $is_product ) {
|
||||
$base[] = 'product';
|
||||
$base[] = 'shop';
|
||||
$new_link = $this->remove_base_from_url( $new_link );
|
||||
}
|
||||
|
||||
foreach ( array_unique( $base ) as $remove ) {
|
||||
if ( '%product_cat%' === $remove ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_link = ! Str::starts_with( '/', $new_link ) ? '/' . $new_link : $new_link;
|
||||
$new_link = preg_replace( "#/{$remove}/#i", '', $new_link, 1 );
|
||||
}
|
||||
|
||||
$new_link = implode( '/', array_map( 'rawurlencode', explode( '/', ltrim( $new_link, '/' ) ) ) ); // encode everything but slashes.
|
||||
|
||||
return $new_link === $this->strip_ignored_parts( $url ) ? false : trailingslashit( home_url( strtolower( $new_link ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all bases from the product link.
|
||||
*
|
||||
* @param string $link Product link.
|
||||
* @return string Modified URL
|
||||
*/
|
||||
private function remove_base_from_url( $link ) {
|
||||
if ( is_feed() ) {
|
||||
return $link;
|
||||
}
|
||||
|
||||
if ( Sitepress::get()->is_active() ) {
|
||||
global $sitepress_settings;
|
||||
|
||||
// Early bail if auto-translation is enabled in WPML.
|
||||
if (
|
||||
isset( $sitepress_settings['custom_posts_sync_option'] ) &&
|
||||
isset( $sitepress_settings['custom_posts_sync_option']['product'] ) &&
|
||||
2 === (int) $sitepress_settings['custom_posts_sync_option']['product']
|
||||
) {
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
|
||||
$link = trim( str_replace( Helper::get_home_url(), '', get_permalink() ), '/' );
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get source URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_source_url() {
|
||||
global $wp;
|
||||
$url = defined( 'TRP_PLUGIN_DIR' ) ? $wp->request : Param::server( 'REQUEST_URI' );
|
||||
$url = str_replace( home_url( '/' ), '', $url );
|
||||
$url = urldecode( $url );
|
||||
$url = trim( Redirection::strip_subdirectory( $url ), '/' );
|
||||
|
||||
$url = explode( '?', $url );
|
||||
$url = trim( $url[0], '/' );
|
||||
|
||||
if ( $this->is_amp_endpoint() ) {
|
||||
$url = \str_replace( '/' . \amp_get_slug(), '', $url );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is AMP url.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_amp_endpoint() {
|
||||
return \function_exists( 'is_amp_endpoint' ) && \function_exists( 'amp_is_canonical' ) && is_amp_endpoint() && ! amp_is_canonical();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unneeded parts from the URI.
|
||||
*
|
||||
* @param string $uri Original URI.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function strip_ignored_parts( $uri ) {
|
||||
$ignore_url_parts = [
|
||||
'#/comment-page-([0-9]{1,})$#',
|
||||
];
|
||||
|
||||
$ignore_url_parts = $this->do_filter( 'woocommerce/product_redirection_ignore_url_parts', $ignore_url_parts );
|
||||
foreach ( $ignore_url_parts as $pattern ) {
|
||||
$uri = preg_replace( $pattern, '', $uri );
|
||||
}
|
||||
|
||||
return implode( '/', array_map( 'rawurlencode', explode( '/', $uri ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can redirect to the new product link.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function can_redirect() {
|
||||
global $wp_query;
|
||||
|
||||
if (
|
||||
$this->do_filter( 'woocommerce/product_redirection', true ) &&
|
||||
! isset( $_GET['elementor-preview'] ) && // phpcs:ignore
|
||||
! isset( $wp_query->query_vars['schema-preview'] ) &&
|
||||
( ( Helper::get_settings( 'general.wc_remove_product_base' ) && is_product() ) ||
|
||||
( Helper::get_settings( 'general.wc_remove_category_base' ) && is_product_category() ) )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce product sitemaps adjustments.
|
||||
*
|
||||
* @since 1.0.32
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Helpers\Attachment;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC Sitemap class.
|
||||
*/
|
||||
class Sitemap {
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*/
|
||||
public function sitemap() {
|
||||
$this->filter( 'rank_math/sitemap/exclude_post_type', 'sitemap_exclude_post_type', 10, 2 );
|
||||
$this->filter( 'rank_math/sitemap/post_type_archive_link', 'sitemap_taxonomies', 10, 2 );
|
||||
$this->filter( 'rank_math/sitemap/post_type_archive_link', 'sitemap_post_type_archive_link', 10, 2 );
|
||||
$this->filter( 'rank_math/sitemap/urlimages', 'add_product_images_to_xml_sitemap', 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure product variations and shop coupons are not included in the XML sitemap.
|
||||
*
|
||||
* @param bool $bool Whether or not to include this post type in the XML sitemap.
|
||||
* @param string $post_type The post type of the post.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sitemap_exclude_post_type( $bool, $post_type ) {
|
||||
if ( in_array( $post_type, [ 'product_variation', 'shop_coupon' ], true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure product attribute taxonomies are not included in the XML sitemap.
|
||||
*
|
||||
* @param bool $bool Whether or not to include this post type in the XML sitemap.
|
||||
* @param string $taxonomy The taxonomy to check against.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sitemap_taxonomies( $bool, $taxonomy ) {
|
||||
if ( in_array( $taxonomy, [ 'product_type', 'product_shipping_class', 'shop_order_status' ], true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( Str::starts_with( 'pa_', $taxonomy ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the archive link on the product sitemap.
|
||||
*
|
||||
* @param string $link The archive link.
|
||||
* @param string $post_type The post type to check against.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sitemap_post_type_archive_link( $link, $post_type ) {
|
||||
if ( 'product' !== $post_type || ! function_exists( 'wc_get_page_id' ) ) {
|
||||
return $link;
|
||||
}
|
||||
|
||||
$shop_page_id = wc_get_page_id( 'shop' );
|
||||
$home_page_id = (int) get_option( 'page_on_front' );
|
||||
if ( 1 > $shop_page_id || 'publish' !== get_post_status( $shop_page_id ) || $home_page_id === $shop_page_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$robots = Helper::get_post_meta( 'robots', $shop_page_id );
|
||||
if ( ! empty( $robots ) && is_array( $robots ) && in_array( 'noindex', $robots, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the product gallery images to the XML sitemap.
|
||||
*
|
||||
* @param array $images The array of images for the post.
|
||||
* @param int $post_id The ID of the post object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_product_images_to_xml_sitemap( $images, $post_id ) {
|
||||
if ( metadata_exists( 'post', $post_id, '_product_image_gallery' ) ) {
|
||||
$product_gallery = get_post_meta( $post_id, '_product_image_gallery', true );
|
||||
$attachments = array_filter( explode( ',', $product_gallery ) );
|
||||
foreach ( $attachments as $attachment_id ) {
|
||||
$image_src = wp_get_attachment_image_src( $attachment_id, 'full' );
|
||||
if ( empty( $image_src ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$image = [
|
||||
'src' => $this->do_filter( 'sitemap/xml_img_src', $image_src[0], $post_id ),
|
||||
'title' => get_the_title( $attachment_id ),
|
||||
'alt' => Attachment::get_alt_tag( $attachment_id ),
|
||||
];
|
||||
$images[] = $image;
|
||||
|
||||
unset( $image, $image_src );
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
}
|
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Register additional variables for WooCommerce.
|
||||
*
|
||||
* @since 1.0.32
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC Variables class.
|
||||
*/
|
||||
class WC_Vars extends Opengraph {
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->action( 'rank_math/vars/register_extra_replacements', 'register' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers variable replacements for WooCommerce products.
|
||||
*/
|
||||
public function register() {
|
||||
rank_math_register_var_replacement(
|
||||
'wc_price',
|
||||
[
|
||||
'name' => esc_html__( 'Product\'s price.', 'rank-math' ),
|
||||
'description' => esc_html__( 'Product\'s price of the current product', 'rank-math' ),
|
||||
'variable' => 'wc_price',
|
||||
'example' => $this->get_product_price(),
|
||||
],
|
||||
[ $this, 'get_product_price' ]
|
||||
);
|
||||
|
||||
rank_math_register_var_replacement(
|
||||
'wc_sku',
|
||||
[
|
||||
'name' => esc_html__( 'Product\'s SKU.', 'rank-math' ),
|
||||
'description' => esc_html__( 'Product\'s SKU of the current product', 'rank-math' ),
|
||||
'variable' => 'wc_sku',
|
||||
'example' => $this->get_product_sku(),
|
||||
],
|
||||
[ $this, 'get_product_sku' ]
|
||||
);
|
||||
|
||||
rank_math_register_var_replacement(
|
||||
'wc_shortdesc',
|
||||
[
|
||||
'name' => esc_html__( 'Product\'s short description.', 'rank-math' ),
|
||||
'description' => esc_html__( 'Product\'s short description of the current product', 'rank-math' ),
|
||||
'variable' => 'wc_shortdesc',
|
||||
'example' => $this->get_short_description(),
|
||||
],
|
||||
[ $this, 'get_short_description' ]
|
||||
);
|
||||
|
||||
rank_math_register_var_replacement(
|
||||
'wc_brand',
|
||||
[
|
||||
'name' => esc_html__( 'Product\'s brand.', 'rank-math' ),
|
||||
'description' => esc_html__( 'Product\'s brand of the current product', 'rank-math' ),
|
||||
'variable' => 'wc_brand',
|
||||
'example' => $this->get_product_brand(),
|
||||
],
|
||||
[ $this, 'get_product_brand' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the product price.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_product_price() {
|
||||
$product = $this->get_product();
|
||||
if ( ! is_object( $product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( method_exists( $product, 'get_price' ) ) {
|
||||
return wp_strip_all_tags( wc_price( $product->get_price() ), true );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the product SKU.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_product_sku() {
|
||||
$product = $this->get_product();
|
||||
if ( ! is_object( $product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( method_exists( $product, 'get_sku' ) ) {
|
||||
return $product->get_sku();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if product class has a short description method.
|
||||
* Otherwise it returns the value of the post_excerpt from the post attribute.
|
||||
*
|
||||
* @param WC_Product $product The product.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_short_description( $product = null ) {
|
||||
if ( empty( $product ) ) {
|
||||
$product = $this->get_product();
|
||||
}
|
||||
|
||||
if ( ! is_object( $product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( method_exists( $product, 'get_short_description' ) ) {
|
||||
return $product->get_short_description();
|
||||
}
|
||||
|
||||
return $product->post->post_excerpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the product brand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_product_brand() {
|
||||
$product = $this->get_product();
|
||||
if ( ! is_object( $product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->get_brands( $product->get_id() );
|
||||
}
|
||||
}
|
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/**
|
||||
* The WooCommerce module.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\WooCommerce;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Traits\Hooker;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Helpers\Param;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WooCommerce class.
|
||||
*/
|
||||
class WooCommerce extends WC_Vars {
|
||||
|
||||
use Hooker;
|
||||
|
||||
/**
|
||||
* Holds the product object.
|
||||
*
|
||||
* @var WC_Product
|
||||
*/
|
||||
private $product = null;
|
||||
|
||||
/**
|
||||
* Remove product base.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $remove_product_base;
|
||||
|
||||
/**
|
||||
* Remove category base.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $remove_category_base;
|
||||
|
||||
/**
|
||||
* Remove parent slugs.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $remove_parent_slugs;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->remove_product_base = Helper::get_settings( 'general.wc_remove_product_base' );
|
||||
$this->remove_category_base = Helper::get_settings( 'general.wc_remove_category_base' );
|
||||
$this->remove_parent_slugs = Helper::get_settings( 'general.wc_remove_category_parent_slugs' );
|
||||
|
||||
if ( is_admin() ) {
|
||||
new Admin();
|
||||
}
|
||||
|
||||
$this->integrations();
|
||||
|
||||
if ( $this->remove_product_base || $this->remove_category_base ) {
|
||||
new Product_Redirection();
|
||||
}
|
||||
|
||||
new Permalink_Watcher();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize integrations.
|
||||
*/
|
||||
public function integrations() {
|
||||
if ( is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Permalink Manager.
|
||||
if ( $this->remove_product_base ) {
|
||||
$this->action( 'request', 'request', 11 );
|
||||
}
|
||||
|
||||
if ( Helper::get_settings( 'general.wc_remove_generator' ) ) {
|
||||
remove_action( 'get_the_generator_html', 'wc_generator_tag', 10 );
|
||||
remove_action( 'get_the_generator_xhtml', 'wc_generator_tag', 10 );
|
||||
}
|
||||
|
||||
$this->sitemap();
|
||||
$this->opengraph();
|
||||
$this->filter( 'rank_math/frontend/description', 'metadesc' );
|
||||
$this->filter( 'rank_math/frontend/robots', 'robots' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace request if product was found.
|
||||
*
|
||||
* @param array $request Current request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function request( $request ) {
|
||||
global $wp, $wpdb;
|
||||
$url = $wp->request;
|
||||
|
||||
if ( empty( $url ) ) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
$replace = [];
|
||||
$url = explode( '/', $url );
|
||||
$slug = array_pop( $url );
|
||||
|
||||
if ( 'feed' === $slug ) {
|
||||
$replace['feed'] = $slug;
|
||||
$slug = array_pop( $url );
|
||||
}
|
||||
|
||||
if ( 'amp' === $slug ) {
|
||||
$replace['amp'] = $slug;
|
||||
$slug = array_pop( $url );
|
||||
}
|
||||
|
||||
if ( 0 === strpos( $slug, 'comment-page-' ) ) {
|
||||
$replace['cpage'] = substr( $slug, strlen( 'comment-page-' ) );
|
||||
$slug = array_pop( $url );
|
||||
}
|
||||
|
||||
if ( 0 === strpos( $slug, 'schema-preview' ) ) {
|
||||
$replace['schema-preview'] = '';
|
||||
$slug = array_pop( $url );
|
||||
}
|
||||
|
||||
$query = "SELECT COUNT(ID) as count_id FROM {$wpdb->posts} WHERE post_name = %s AND post_type = %s";
|
||||
$num = intval( $wpdb->get_var( $wpdb->prepare( $query, [ $slug, 'product' ] ) ) ); // phpcs:ignore
|
||||
if ( $num > 0 ) {
|
||||
$replace['page'] = '';
|
||||
$replace['name'] = $slug;
|
||||
$replace['product'] = $slug;
|
||||
$replace['post_type'] = 'product';
|
||||
|
||||
return $replace;
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change robots for WooCommerce pages according to the settings.
|
||||
*
|
||||
* @param array $robots Array of robots to sanitize.
|
||||
*
|
||||
* @return array Modified robots.
|
||||
*/
|
||||
public function robots( $robots ) {
|
||||
|
||||
// Early Bail if current page is Woocommerce OnePage Checkout.
|
||||
if ( function_exists( 'is_wcopc_checkout' ) && is_wcopc_checkout() ) {
|
||||
return $robots;
|
||||
}
|
||||
|
||||
if ( is_cart() || is_checkout() || is_account_page() ) {
|
||||
remove_action( 'wp_head', 'wc_page_noindex' );
|
||||
return [
|
||||
'index' => 'noindex',
|
||||
'follow' => 'follow',
|
||||
];
|
||||
}
|
||||
|
||||
return $robots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the meta description. Checks which value should be used when the given meta description is empty.
|
||||
*
|
||||
* It will use the short_description if that one is set. Otherwise it will use the full
|
||||
* product description limited to 156 characters. If everything is empty, it will return an empty string.
|
||||
*
|
||||
* @param string $metadesc The meta description to check.
|
||||
*
|
||||
* @return string The meta description.
|
||||
*/
|
||||
public function metadesc( $metadesc ) {
|
||||
if ( '' !== $metadesc || ! is_singular( 'product' ) ) {
|
||||
return $metadesc;
|
||||
}
|
||||
|
||||
$product = $this->get_product_by_id( get_the_id() );
|
||||
if ( ! is_object( $product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$short_desc = $this->get_short_description( $product );
|
||||
if ( '' !== $short_desc ) {
|
||||
return $short_desc;
|
||||
}
|
||||
|
||||
$long_desc = $this->get_long_description( $product );
|
||||
return '' !== $long_desc ? Str::truncate( $long_desc, 156 ) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product for given product_id.
|
||||
*
|
||||
* @param int $product_id The id to get the product for.
|
||||
*
|
||||
* @return null|WC_Product
|
||||
*/
|
||||
protected function get_product_by_id( $product_id ) {
|
||||
if ( function_exists( 'wc_get_product' ) ) {
|
||||
return wc_get_product( $product_id );
|
||||
}
|
||||
|
||||
if ( function_exists( 'get_product' ) ) {
|
||||
return get_product( $product_id );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if product class has a description method.
|
||||
* Otherwise it returns the value of the post_content.
|
||||
*
|
||||
* @param WC_Product $product The product.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_long_description( $product ) {
|
||||
if ( method_exists( $product, 'get_description' ) ) {
|
||||
return $product->get_description();
|
||||
}
|
||||
|
||||
return $product->post->post_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product object when the current page is the product page.
|
||||
*
|
||||
* @return null|WC_Product
|
||||
*/
|
||||
public function get_product() {
|
||||
if ( ! is_null( $this->product ) ) {
|
||||
return $this->product;
|
||||
}
|
||||
|
||||
$product_id = Param::get( 'post', get_queried_object_id(), FILTER_VALIDATE_INT );
|
||||
$this->product = (
|
||||
! function_exists( 'wc_get_product' ) ||
|
||||
! $product_id ||
|
||||
(
|
||||
! is_admin() &&
|
||||
! is_singular( 'product' )
|
||||
)
|
||||
) ? null : wc_get_product( $product_id );
|
||||
|
||||
return $this->product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of brand taxonomy.
|
||||
*
|
||||
* @param int $product_id The id to get the product brands for.
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public static function get_brands( $product_id ) {
|
||||
$brand = '';
|
||||
$taxonomy = Helper::get_settings( 'general.product_brand' );
|
||||
if ( $taxonomy && taxonomy_exists( $taxonomy ) ) {
|
||||
$brands = get_the_terms( $product_id, $taxonomy );
|
||||
$brand = is_wp_error( $brands ) || empty( $brands[0] ) ? '' : $brands[0]->name;
|
||||
}
|
||||
|
||||
return apply_filters( 'rank_math/woocommerce/product_brand', $brand );
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce general settings.
|
||||
*
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\WooCommerce
|
||||
*/
|
||||
|
||||
use RankMath\Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'wc_remove_product_base',
|
||||
'type' => 'toggle',
|
||||
'name' => esc_html__( 'Remove base', 'rank-math' ),
|
||||
'desc' => sprintf(
|
||||
/* translators: 1. Example text 2. Example text */
|
||||
esc_html__( 'Remove prefix like %1$s from product URL chosen at %2$s', 'rank-math' ),
|
||||
'<code>/shop/*</code>, <code>/product/*</code>',
|
||||
'<br /><code>' . __( 'WordPress Dashboard > Settings > Permalinks > Product permalinks Example: default: /product/accessories/action-figures/acme/ - becomes: /accessories/action-figures/acme/', 'rank-math' ) . '</code>'
|
||||
),
|
||||
'default' => 'off',
|
||||
'classes' => 'rank-math-advanced-option',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'wc_remove_category_base',
|
||||
'type' => 'toggle',
|
||||
'name' => esc_html__( 'Remove category base', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Remove prefix from category URL.', 'rank-math' ) .
|
||||
'<br><code>' . esc_html__( 'default: /product-category/accessories/action-figures/ - changed: /accessories/action-figures/', 'rank-math' ) . '</code>',
|
||||
'default' => 'off',
|
||||
'classes' => 'rank-math-advanced-option',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'wc_remove_category_parent_slugs',
|
||||
'type' => 'toggle',
|
||||
'name' => esc_html__( ' Remove parent slugs', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Remove parent slugs from category URL.', 'rank-math' ) .
|
||||
'<br><code>' . esc_html__( 'default: /product-category/accessories/action-figures/ - changed: /product-category/action-figures/', 'rank-math' ) . '</code>',
|
||||
'default' => 'off',
|
||||
'classes' => 'rank-math-advanced-option',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'wc_remove_generator',
|
||||
'type' => 'toggle',
|
||||
'name' => esc_html__( 'Remove Generator Tag', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Remove WooCommerce generator tag from the source code.', 'rank-math' ),
|
||||
'default' => 'on',
|
||||
'classes' => 'rank-math-advanced-option',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'remove_shop_snippet_data',
|
||||
'type' => 'toggle',
|
||||
'name' => esc_html__( 'Remove Schema Markup on Shop Archives', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Remove Schema Markup Data from WooCommerce Shop archive pages.', 'rank-math' ),
|
||||
'default' => 'on',
|
||||
'classes' => 'rank-math-advanced-option',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'product_brand',
|
||||
'type' => 'select',
|
||||
'name' => esc_html__( 'Brand', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Select Product Brand Taxonomy to use in Schema.org & OpenGraph markup.', 'rank-math' ),
|
||||
'options' => Helper::get_object_taxonomies( 'product', 'choices', false ),
|
||||
]
|
||||
);
|
Reference in New Issue
Block a user