I am using Wordpress (v 5.3) with WooCommerce (v 3.8.1). My facebook pixel registers events (ViewContent/InitiateCheckout/AddToCart/Purchase/etc.) on desktop, but doesn't register events on mobile (iOS). All my plugins and theme are up to date. For my theme, I am using Youplay (v 3.7.4).
In searching for an answer, I have noticed some people who have had problems with their theme obstructing Facebook Pixel from working on mobile - some people reported needing to comment out a line in functions.php - I am including my theme's functions.php incase anyone notices anything that might conflict with Facebook Pixel working on mobile (in the posts I found, nobody was using the same theme as me):
functions.php
<?php
/**
* Youplay functions and definitions
*
* #package Youplay
*/
add_action( 'after_setup_theme', 'yp_setup' );
if ( ! function_exists( 'yp_setup' ) ) :
/**
* Sets up theme defaults and registers support for various WordPress features.
*
* Note that this function is hooked into the after_setup_theme hook, which
* runs before the init hook. The init hook is too late for some features, such
* as indicating support for post thumbnails.
*/
function yp_setup() {
/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on Youplay, use a find and replace
* to change 'youplay' to the name of your theme in all the template files
*/
load_theme_textdomain( 'youplay', get_template_directory() . '/languages' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded <title> tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support( 'title-tag' );
// Add editor style support.
add_editor_style();
/*
* Enable support for Post Thumbnails on posts and pages.
*
* #link http://codex.wordpress.org/Function_Reference/add_theme_support#Post_Thumbnails
*/
// This theme uses wp_nav_menu() in one location.
register_nav_menus( array(
'primary' => esc_html__( 'Primary Menu', 'youplay' ),
'primary-right' => esc_html__( 'Primary Right Menu', 'youplay' ),
) );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support( 'html5', array(
'search-form', 'comment-form', 'comment-list', 'gallery', 'caption',
) );
/*
* Enable support for WooCommerce
*/
add_theme_support( 'woocommerce' );
// Add default image sizes
add_theme_support('post-thumbnails');
add_image_size('500x375', 500);
add_image_size('500x375_crop', 500, 375, true);
add_image_size('200x200', 200, 200, true);
add_image_size('90x90', 90, 90, true);
add_image_size('1440x900', 1440);
add_image_size('1440x900_crop', 1440, 900, true);
add_image_size('1920x1080', 1920);
// Register the three useful image sizes for use in Add Media modal
add_filter( 'image_size_names_choose', 'yp_custom_sizes' );
if ( ! function_exists( 'yp_custom_sizes' ) ) :
function yp_custom_sizes( $sizes ) {
return array_merge( $sizes, array(
'500x375_crop' => esc_html__( 'Carousel Thumbnail (500x375 crop)', 'youplay' ),
'500x375' => esc_html__( 'Carousel Thumbnail (500x375)', 'youplay' ),
'200x200' => esc_html__( 'User Avatar (200x200 crop)', 'youplay' ),
'90x90' => esc_html__( 'User Small Avatar (90x90 crop)', 'youplay' ),
'1440x900_crop' => esc_html__( '1440x900 crop', 'youplay' ),
'1440x900' => esc_html__( '1440x900', 'youplay' ),
'1920x1080' => esc_html__( '1920x1080', 'youplay' ),
) );
}
endif;
}
endif; // yp_setup
/**
* Set the content width in pixels, based on the theme's design and stylesheet.
*/
if (!isset($content_width)) {
$content_width = 1400;
}
/**
* Register widget area.
*
* #link http://codex.wordpress.org/Function_Reference/register_sidebar
*/
add_action( 'widgets_init', 'yp_widgets_init' );
if ( ! function_exists( 'yp_widgets_init' ) ) :
function yp_widgets_init() {
register_sidebar( array(
'name' => esc_html__( 'Sidebar', 'youplay' ),
'id' => 'sidebar-1',
'description' => esc_html__( 'Default Sidebar', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'WooCommerce Sidebar', 'youplay' ),
'id' => 'woocommerce_sidebar',
'description' => esc_html__( 'Sidebar for WooCommerce Pages', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'BuddyPress Sidebar', 'youplay' ),
'id' => 'buddypress_sidebar',
'description' => esc_html__( 'Sidebar for BuddyPress Pages', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'bbPress Sidebar', 'youplay' ),
'id' => 'bbpress_sidebar',
'description' => esc_html__( 'Sidebar for bbPress Pages', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'Matches Sidebar', 'youplay' ),
'id' => 'matches_sidebar',
'description' => esc_html__( 'Sidebar for Matches Pages', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'Footer Widgets 1', 'youplay' ),
'id' => 'footer_widgets_1',
'description' => esc_html__( 'Footer Widgets 1 Column', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'Footer Widgets 2', 'youplay' ),
'id' => 'footer_widgets_2',
'description' => esc_html__( 'Footer Widgets 2 Column', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'Footer Widgets 3', 'youplay' ),
'id' => 'footer_widgets_3',
'description' => esc_html__( 'Footer Widgets 3 Column', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
register_sidebar( array(
'name' => esc_html__( 'Footer Widgets 4', 'youplay' ),
'id' => 'footer_widgets_4',
'description' => esc_html__( 'Footer Widgets 4 Column', 'youplay' ),
'before_widget' => '<div id="%1$s" class="side-block widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widget-title block-title">',
'after_title' => '</h4>',
) );
}
endif;
/**
* Enqueue scripts and styles.
*/
add_action( 'wp_enqueue_scripts', 'yp_scripts' );
if ( ! function_exists( 'yp_scripts' ) ) :
function yp_scripts() {
wp_enqueue_style( 'youplay', get_template_directory_uri() . '/style.css', '', '3.7.4' );
wp_enqueue_style( 'bootstrap', get_template_directory_uri() . '/assets/vendor/bootstrap/dist/css/bootstrap.min.css', '', '3.3.7' );
wp_enqueue_style( 'magnific-popup', get_template_directory_uri() . '/assets/vendor/magnific-popup/dist/magnific-popup.css', '', '1.1.0' );
wp_enqueue_style( 'flickity', get_template_directory_uri() . '/assets/vendor/flickity/dist/flickity.min.css', '', '2.2.0' );
// deregister bbPress styles
wp_deregister_style( 'bbp-default' );
wp_register_style( 'bbp-default', get_template_directory_uri() . '/assets/css/bbpress-styles.css' );
// theme style
$theme_style = yp_opts('theme_style');
$youplay_style_file = '';
$youplay_style_version = '3.7.4';
if ($theme_style === 'custom') {
youplay_maybe_compile_scss();
if ( function_exists('nk_theme') ) {
$youplay_style_file = nk_theme()->get_compiled_css_url('youplay-custom.min.css');
$youplay_style_version = nk_theme()->get_compiled_css_version('youplay-custom.min.css');
}
if (!$youplay_style_file) {
$theme_style = 'dark';
}
}
if($theme_style !== 'custom') {
$youplay_style_file = get_template_directory_uri() . '/assets/css/youplay-' . $theme_style . '.min.css';
}
wp_enqueue_style('youplay-' . $theme_style, $youplay_style_file, array(), $youplay_style_version);
// rtl
if(yp_opts('general_rtl')) {
wp_enqueue_style( 'youplay-rtl', get_template_directory_uri() . '/assets/css/youplay-rtl.min.css', '', '3.7.4' );
}
wp_enqueue_script( 'bootstrap', get_template_directory_uri() . '/assets/vendor/bootstrap/dist/js/bootstrap.min.js', array('jquery'), '3.3.7', true );
wp_enqueue_script( 'font-awesome', get_template_directory_uri() . '/assets/vendor/fontawesome-free/js/all.js', array(), '5.9.0', true );
wp_enqueue_script( 'font-awesome-v4-shims', get_template_directory_uri() . '/assets/vendor/fontawesome-free/js/v4-shims.js', array('font-awesome'), '5.9.0', true );
wp_enqueue_script( 'isotope', get_template_directory_uri() . '/assets/vendor/isotope-layout/dist/isotope.pkgd.min.js', array('jquery', 'imagesloaded'), '3.0.6', true );
wp_enqueue_script( 'jquery-countdown', get_template_directory_uri() . '/assets/vendor/jquery-countdown/dist/jquery.countdown.min.js', array('jquery'), '2.2.0', true );
wp_enqueue_script( 'moment-timezone', get_template_directory_uri() . '/assets/vendor/moment-timezone/builds/moment-timezone-with-data.min.js', array('moment'), '0.5.14', true );
wp_enqueue_script( 'magnific-popup', get_template_directory_uri() . '/assets/vendor/magnific-popup/dist/jquery.magnific-popup.min.js', '', '1.1.0', true );
wp_enqueue_script( 'flickity', get_template_directory_uri() . '/assets/vendor/flickity/dist/flickity.pkgd.min.js', array('jquery', 'imagesloaded'), '2.2.0', true );
wp_enqueue_script( 'object-fit-images', get_template_directory_uri() . '/assets/vendor/object-fit-images/dist/ofi.min.js', '', '3.2.3', true );
wp_enqueue_script( 'jarallax', get_template_directory_uri() . '/assets/vendor/jarallax/dist/jarallax.min.js', '', '1.10.7', true );
wp_enqueue_script( 'skrollr', get_template_directory_uri() . '/assets/vendor/skrollr/dist/skrollr.min.js', '', '0.6.30', true );
wp_enqueue_script( 'hexagon-progress', get_template_directory_uri() . '/assets/vendor/HexagonProgress/jquery.hexagonprogress.min.js', '', '1.2.0', true );
wp_enqueue_script( 'youplay', get_template_directory_uri() . '/assets/js/youplay.min.js', array('jquery', 'bootstrap', 'isotope', 'imagesloaded', 'jquery-countdown', 'magnific-popup', 'flickity', 'object-fit-images', 'jarallax', 'hexagon-progress'), '3.7.4', true );
wp_enqueue_script( 'youplay-wp', get_template_directory_uri() . '/assets/js/youplay-wp.min.js', array('jquery', 'youplay'), '3.7.4', true );
wp_enqueue_script( 'youplay-cf7', get_template_directory_uri() . '/assets/js/youplay-cf7.min.js', array('jquery', 'youplay'), '3.7.4', true );
wp_enqueue_script( 'youplay-init', get_template_directory_uri() . '/assets/js/youplay-init.min.js', array('jquery', 'youplay'), '3.7.4', true );
$dataInit = array(
'enableParallax' => yp_opts('general_parallax'),
'enableFadeBetweenPages' => yp_opts('general_fade_between_pages') && yp_opts('general_preloader')
);
wp_localize_script('youplay-init', 'youplayInitOptions', $dataInit);
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
// Custom CSS
ob_start();
require get_template_directory() . '/inc/head_styles.php';
$custom_css = ob_get_clean();
$custom_css = wp_kses( $custom_css, array( '\'', '\"' ) );
$custom_css = str_replace( '>' , '>' , $custom_css );
wp_add_inline_style( 'youplay-' . $theme_style, $custom_css );
// Custom JS
wp_add_inline_script( 'youplay-init', yp_opts('general_custom_js') );
}
endif;
// Compile SCSS.
if (!function_exists('youplay_maybe_compile_scss')) :
function youplay_maybe_compile_scss() {
if ( yp_opts('theme_style') !== 'custom' || ! function_exists('nk_theme') ) {
return;
}
$theme_colors_from = yp_opts('theme_colors_from') == 'light' ? 'light' : 'dark';
$theme_main_color = yp_opts('theme_main_color');
$theme_back_color = yp_opts('theme_back_color');
$theme_back_grey_color = yp_opts('theme_back_grey_color');
$theme_text_color = yp_opts('theme_text_color');
$theme_primary_color = yp_opts('theme_primary_color');
$theme_success_color = yp_opts('theme_success_color');
$theme_info_color = yp_opts('theme_info_color');
$theme_warning_color = yp_opts('theme_warning_color');
$theme_danger_color = yp_opts('theme_danger_color');
$theme_skew_size = yp_opts('theme_skew_size');
$theme_navbar_height = yp_opts('theme_navbar_height');
$theme_navbar_small_height = yp_opts('theme_navbar_small_height');
$theme_banners_opacity = yp_opts('theme_banners_opacity') / 100;
$theme_images_opacity = yp_opts('theme_images_opacity') / 100;
$theme_images_hover_opacity = yp_opts('theme_images_hover_opacity') / 100;
$theme_data = wp_get_theme();
$theme_parent = $theme_data->parent();
if (!empty($theme_parent)) {
$theme_data = $theme_parent;
}
$theme_version = $theme_data['Version'];
$path = get_template_directory() . '/assets/css/';
$custom_vars = '
#import "_helpers.scss";
#import "_variables.scss";
$theme_version:"' . $theme_version . '";
$theme:' . $theme_colors_from . ';
$main_color:' . $theme_main_color . ';
$back_color:' . $theme_back_color . ';
$back_darken_color:' . ($theme_colors_from == 'light' ? '#FFFFFF' : 'darken($back_color, 13)' ) . ';
$back_grey_color:' . $theme_back_grey_color . ';
$back_darken_grey_color: ' . ($theme_colors_from == 'light' ? 'lighten' : 'darken') . '($back_grey_color, 10);
$text_color:' . $theme_text_color . ';
$text_mute_color: rgba($text_color, 0.5);
$color_primary:' . $theme_primary_color . ';
$color_success:' . $theme_success_color . ';
$color_info:' . $theme_info_color . ';
$color_warning:' . $theme_warning_color . ';
$color_danger:' . $theme_danger_color . ';
$skew_size:' . $theme_skew_size . 'deg;
$banners_opacity:' . $theme_banners_opacity . ';
$images_opacity:' . $theme_images_opacity . ';
$images_hover_opacity:' . $theme_images_hover_opacity . ';
$navbar-height:' . $theme_navbar_height . 'px;
$navbar-sm-height:' . $theme_navbar_small_height . 'px;
#import "_includes.scss"';
nk_theme()->scss('youplay-custom.min.css', $path, $custom_vars);
}
endif;
add_action('ot_after_theme_options_save', 'youplay_maybe_compile_scss');
/**
* Admin References
*/
require get_template_directory() . '/admin/admin.php';
/**
* Custom functions that act independently of the theme templates.
*/
require get_template_directory() . '/inc/extras.php';
/**
* Colors convert functions
*/
require get_template_directory() . '/inc/colors.php';
/**
* Custom template tags for this theme.
*/
require get_template_directory() . '/inc/template-tags.php';
/**
* Comments walker
*/
require get_template_directory() . '/inc/comments-walker.php';
/**
* Custom WooCommerce functions
*/
require get_template_directory() . '/woocommerce/functions.php';
/**
* Custom BuddyPress functions
*/
require get_template_directory() . '/buddypress/functions.php';
/**
* Custom bbPress functions
*/
require get_template_directory() . '/bbpress/functions.php';
/**
* Infinitie Scroll for Posts
*/
require get_template_directory() . '/inc/lib/nk-infinite-scroll/nk-infinitie-scroll.php';
I also found someone who said that their theme was removing a WooCommerce hook (I believe it was woocommerce_after_single_product but I am not exactly where I read that anymore) - I am not sure if my theme is doing that.
I have verified that all the Facebook Pixel events show up when I am not on mobile:
You can see that it is showing Receiving activity and has events listed. When I try on mobile, it say that it is not Receiving activity (there is a yellow dot), and it does not report the events.
I found the source code where the events are handled in facebook-commerce-events-tracker.php, maybe something in there isn't mobile friendly? I am showing only what I think may be relevant because I have no more room for text in this question:
facebook-commerce-events-tracker.php
...
class WC_Facebookcommerce_EventsTracker {
private $pixel;
private static $isEnabled = true;
const FB_PRIORITY_HIGH = 2;
const FB_PRIORITY_LOW = 11;
public function __construct( $user_info ) {
$this->pixel = new WC_Facebookcommerce_Pixel( $user_info );
add_action( 'wp_head', array( $this, 'apply_filters' ) );
// Pixel Tracking Hooks
add_action(
'wp_head',
array( $this, 'inject_base_pixel' )
);
add_action(
'wp_footer',
array( $this, 'inject_base_pixel_noscript' )
);
add_action(
'woocommerce_after_single_product',
array( $this, 'inject_view_content_event' ),
self::FB_PRIORITY_HIGH
);
add_action(
'woocommerce_after_shop_loop',
array( $this, 'inject_view_category_event' )
);
add_action(
'pre_get_posts',
array( $this, 'inject_search_event' )
);
add_action(
'woocommerce_after_cart',
array( $this, 'inject_add_to_cart_redirect_event' )
);
add_action(
'woocommerce_add_to_cart',
array( $this, 'inject_add_to_cart_event' ),
self::FB_PRIORITY_HIGH
);
add_action(
'wc_ajax_fb_inject_add_to_cart_event',
array( $this, 'inject_ajax_add_to_cart_event' ),
self::FB_PRIORITY_HIGH
);
add_action(
'woocommerce_after_checkout_form',
array( $this, 'inject_initiate_checkout_event' )
);
add_action(
'woocommerce_thankyou',
array( $this, 'inject_gateway_purchase_event' ),
self::FB_PRIORITY_HIGH
);
add_action(
'woocommerce_payment_complete',
array( $this, 'inject_purchase_event' ),
self::FB_PRIORITY_HIGH
);
add_action(
'wpcf7_contact_form',
array( $this, 'inject_lead_event_hook' ),
self::FB_PRIORITY_LOW
);
}
...
/**
* Triggers ViewContent product pages
*/
public function inject_view_content_event() {
if ( ! self::$isEnabled ) {
return;
}
global $post;
$product = wc_get_product( $post->ID );
$content_type = 'product_group';
if ( ! $product ) {
return;
}
// if product is a variant, fire the pixel with content_type: product_group
if ( WC_Facebookcommerce_Utils::is_variation_type( $product->get_type() ) ) {
$content_type = 'product';
}
$content_ids = WC_Facebookcommerce_Utils::get_fb_content_ids( $product );
$this->pixel->inject_event(
'ViewContent',
array(
'content_name' => $product->get_title(),
'content_ids' => json_encode( $content_ids ),
'content_type' => $content_type,
'value' => $product->get_price(),
'currency' => get_woocommerce_currency(),
)
);
}
Here is the inject_event function referenced above:
/**
* Preferred method to inject events in a page, normally you should use this
* instead of WC_Facebookcommerce_Pixel::build_event()
*/
public function inject_event( $event_name, $params, $method = 'track' ) {
$code = self::build_event( $event_name, $params, $method );
$this->last_event = $event_name;
if ( WC_Facebookcommerce_Utils::isWoocommerceIntegration() ) {
WC_Facebookcommerce_Utils::wc_enqueue_js( $code );
} else {
printf(
'
<!-- Facebook Pixel Event Code -->
<script>
%s
</script>
<!-- End Facebook Pixel Event Code -->
',
$code
);
}
}
I noticed on mobile - the section that should have the Facebook Pixel code looks odd:
<!-- Facebook Pixel Code -->
<noscript>
<img height="1" width="1" style="display:none" alt="fbpx"
src="https://www.facebook.com/tr?id=549560325605747&ev=PageView&noscript=1"/>
</noscript>
<!-- End Facebook Pixel Code -->
Above: Why is there an img element where the Facebook Pixel code should go?
EDIT: For above question, it seems that it is the same for desktop so I don't think this matters - although I don't understand what it is.
I found where the actual event code is on my website when it gets injected - it looks like it is registering as a PageView though, and it should be ViewContent - maybe the categorization being wrong is somehow causing the issue (a conflict)?
<!-- WooCommerce Facebook Integration Begin -->
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
<script>
fbq('init', 'xxxxx', {}, {
"agent": "woocommerce-3.8.1-1.9.15"
});
fbq('track', 'PageView', {
"source": "woocommerce",
"version": "3.8.1",
"pluginVersion": "1.9.15"
});
document.addEventListener('DOMContentLoaded', function() {
jQuery && jQuery(function($){
$('body').on('added_to_cart', function(event) {
// Ajax action.
$.get('?wc-ajax=fb_inject_add_to_cart_event', function(data) {
$('head').append(data);
});
});
});
}, false);
</script>
<!-- DO NOT MODIFY -->
<!-- WooCommerce Facebook Integration end -->
This is what the same section looks like on desktop - I noticed it has an em attribute that is my email that isn't there on the mobile version - maybe this is important and needs to be included when the site is rendered on mobile?
fbq('init', 'xxxx', {
"em": "myemail7#gmail.com"
}, {
"agent": "woocommerce-3.8.1-1.9.15"
});
fbq('track', 'PageView', {
"source": "woocommerce",
"version": "3.8.1",
"pluginVersion": "1.9.15"
});
document.addEventListener('DOMContentLoaded', function() {
jQuery && jQuery(function($){
$('body').on('added_to_cart', function(event) {
// Ajax action.
$.get('?wc-ajax=fb_inject_add_to_cart_event', function(data) {
$('head').append(data);
});
});
});
}, false);
**EDIT:**For above, I learned that the email is there because I am a user of the site on my computer, but not on my phone - so I think that it is ok that my email isn't there for mobile. This is the code that creates the above code in Facebook/WooCommerce source code:
private function pixel_init_code() {
$version_info = self::get_version_info();
$agent_string = sprintf(
'%s-%s-%s',
$version_info['source'],
$version_info['version'],
$version_info['pluginVersion']
);
$params = array(
'agent' => $agent_string,
);
return apply_filters(
'facebook_woocommerce_pixel_init',
sprintf(
"fbq('init', '%s', %s, %s);\n",
esc_js( self::get_pixel_id() ),
json_encode( $this->user_info, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT ),
json_encode( $params, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT )
)
);
}
EDIT: I found where the ViewContent Facebook Pixel tracking code is - it is at the bottom of the page for both mobile and desktop and looks the same for both:
jQuery(function($) {
/* WooCommerce Facebook Integration Event Tracking */
fbq('track', 'ViewContent', {
"source": "woocommerce",
"version": "3.8.1",
"pluginVersion": "1.9.15",
"content_name": "Accessory Power ENHANCE ENGXH10100BKEW GX-H1 Gaming Headset - Black, Blue",
"content_ids": "[\"TFL-ENGXH10100BKEW-OPEN-BOX\"]",
"content_type": "product_group",
"value": "39.85",
"currency": "USD"
});
});
Neither event fires on mobile - both fire on desktop.
Why is my Facebook Pixel not working on mobile (iOS)? On my phone, I have tried both with Safari and Chrome.
EDIT
According to the comments I have seen throughout the source code, I believe it should be placing the Facebook Pixel event code in the <footer>, but it seems to be placing it in the <head> instead, would this matter for mobile?
I figured it out, and it wasn't anything wrong with my code - apparently to receive the test events from my phone, I need to be logged into the facebook business manager on my phone or it won't work - and this issue isn't clearly stated really, on the Test Events page it says under the header at the top:
Only events you trigger will display in the Test Events tool, not the
activity of other website users.
So you can see they weren't very clear about how to become the "you" in the above statement (you have to login to the business manager on the actual device you are testing on).
I am using the example from the CMB2 snippets library to add a theme options page in WordPress
/**
* Hook in and register a metabox to handle a theme options page and adds a menu item.
*/
function yourprefix_register_main_options_metabox() {
/**
* Registers main options page menu item and form.
*/
$args = array(
'id' => 'yourprefix_main_options_page',
'title' => 'Main Options',
'object_types' => array( 'options-page' ),
'option_key' => 'yourprefix_main_options',
'tab_group' => 'yourprefix_main_options',
'tab_title' => 'Main',
);
// 'tab_group' property is supported in > 2.4.0.
if ( version_compare( CMB2_VERSION, '2.4.0' ) ) {
$args['display_cb'] = 'yourprefix_options_display_with_tabs';
}
$main_options = new_cmb2_box( $args );
/**
* Options fields ids only need
* to be unique within this box.
* Prefix is not needed.
*/
$main_options->add_field( array(
'name' => 'Site Background Color',
'desc' => 'field description (optional)',
'id' => 'bg_color',
'type' => 'colorpicker',
'default' => '#ffffff',
) );
/**
* Registers secondary options page, and set main item as parent.
*/
$args = array(
'id' => 'yourprefix_secondary_options_page',
'menu_title' => 'Secondary Options', // Use menu title, & not title to hide main h2.
'object_types' => array( 'options-page' ),
'option_key' => 'yourprefix_secondary_options',
'parent_slug' => 'yourprefix_main_options',
'tab_group' => 'yourprefix_main_options',
'tab_title' => 'Secondary',
);
// 'tab_group' property is supported in > 2.4.0.
if ( version_compare( CMB2_VERSION, '2.4.0' ) ) {
$args['display_cb'] = 'yourprefix_options_display_with_tabs';
}
$secondary_options = new_cmb2_box( $args );
$secondary_options->add_field( array(
'name' => 'Test Radio',
'desc' => 'field description (optional)',
'id' => 'radio',
'type' => 'radio',
'options' => array(
'option1' => 'Option One',
'option2' => 'Option Two',
'option3' => 'Option Three',
),
) );
/**
* Registers tertiary options page, and set main item as parent.
*/
$args = array(
'id' => 'yourprefix_tertiary_options_page',
'menu_title' => 'Tertiary Options', // Use menu title, & not title to hide main h2.
'object_types' => array( 'options-page' ),
'option_key' => 'yourprefix_tertiary_options',
'parent_slug' => 'yourprefix_main_options',
'tab_group' => 'yourprefix_main_options',
'tab_title' => 'Tertiary',
);
// 'tab_group' property is supported in > 2.4.0.
if ( version_compare( CMB2_VERSION, '2.4.0' ) ) {
$args['display_cb'] = 'yourprefix_options_display_with_tabs';
}
$tertiary_options = new_cmb2_box( $args );
$tertiary_options->add_field( array(
'name' => 'Test Text Area for Code',
'desc' => 'field description (optional)',
'id' => 'textarea_code',
'type' => 'textarea_code',
) );
}
add_action( 'cmb2_admin_init', 'yourprefix_register_main_options_metabox' );
/**
* A CMB2 options-page display callback override which adds tab navigation among
* CMB2 options pages which share this same display callback.
*
* #param CMB2_Options_Hookup $cmb_options The CMB2_Options_Hookup object.
*/
function yourprefix_options_display_with_tabs( $cmb_options ) {
$tabs = yourprefix_options_page_tabs( $cmb_options );
?>
<div class="wrap cmb2-options-page option-<?php echo $cmb_options->option_key; ?>">
<?php if ( get_admin_page_title() ) : ?>
<h2><?php echo wp_kses_post( get_admin_page_title() ); ?></h2>
<?php endif; ?>
<h2 class="nav-tab-wrapper">
<?php foreach ( $tabs as $option_key => $tab_title ) : ?>
<a class="nav-tab<?php if ( isset( $_GET['page'] ) && $option_key === $_GET['page'] ) : ?> nav-tab-active<?php endif; ?>" href="<?php menu_page_url( $option_key ); ?>"><?php echo wp_kses_post( $tab_title ); ?></a>
<?php endforeach; ?>
</h2>
<form class="cmb-form" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="POST" id="<?php echo $cmb_options->cmb->cmb_id; ?>" enctype="multipart/form-data" encoding="multipart/form-data">
<input type="hidden" name="action" value="<?php echo esc_attr( $cmb_options->option_key ); ?>">
<?php $cmb_options->options_page_metabox(); ?>
<?php submit_button( esc_attr( $cmb_options->cmb->prop( 'save_button' ) ), 'primary', 'submit-cmb' ); ?>
</form>
</div>
<?php
}
/**
* Gets navigation tabs array for CMB2 options pages which share the given
* display_cb param.
*
* #param CMB2_Options_Hookup $cmb_options The CMB2_Options_Hookup object.
*
* #return array Array of tab information.
*/
function yourprefix_options_page_tabs( $cmb_options ) {
$tab_group = $cmb_options->cmb->prop( 'tab_group' );
$tabs = array();
foreach ( CMB2_Boxes::get_all() as $cmb_id => $cmb ) {
if ( $tab_group === $cmb->prop( 'tab_group' ) ) {
$tabs[ $cmb->options_page_keys()[0] ] = $cmb->prop( 'tab_title' )
? $cmb->prop( 'tab_title' )
: $cmb->prop( 'title' );
}
}
return $tabs;
}
This works great, but I can't figure out how to actually get one of these values and display it in a theme. Anyone have an example?
You can use cmb2_get_option()
It takes 3 parameters: cmb2_get_option( $option_key, $field_id, $default );
So in your case:
$option_key = yourprefix_main_options,
$field_id = bg_color,
$default = the default value (in case you set it).
It should look like this:
cmb2_get_option( 'yourprefix_main_options', 'bg_color' );
cmb2_get_option( 'yourprefix_secondary_options', 'radio' );
and so on ..
Also, You can use your own function with Fallback:
/**
* Wrapper function around cmb2_get_option
* #since 0.1.0
* #param string $key Options array key
* #param mixed $default Optional default value
* #return mixed Option value
*/
function myprefix_get_option( $key = '', $default = false ) {
if ( function_exists( 'cmb2_get_option' ) ) {
// Use cmb2_get_option as it passes through some key filters.
return cmb2_get_option( 'yourprefix_main_options', $key, $default );
}
// Fallback to get_option if CMB2 is not loaded yet.
$opts = get_option( 'yourprefix_main_options', $default );
$val = $default;
if ( 'all' == $key ) {
$val = $opts;
} elseif ( is_array( $opts ) && array_key_exists( $key, $opts ) && false !== $opts[ $key ] ) {
$val = $opts[ $key ];
}
return $val;
}
Use it like this:
myprefix_get_option( bg_color )
Please use the following code :
get_option("<your id>");
Like :
get_option('bg_color');
Hope this will work for you.
You can try using array system with get_option() function.
First time you need to use get_option('your-option-key');
like your option-key is "yourprefix_main_options" so you need to use get_option('yourprefix_main_options');
then you can keep your value on variable. like
$main_option_data = get_option('yourprefix_main_options');
then you can use $main_option_data and your filed id as a array. like your one filed id is bg_color so you can use $main_option_data['bg_color'];
You can check my one previous work, I think it will be help you.
// Theme Options
add_action( 'cmb2_admin_init', 'mosc_panel_theme_options_metabox' );
/**
* Hook in and register a metabox to handle a theme options page and adds a menu item.
*/
function mosc_panel_theme_options_metabox() {
/**
* Registers options page menu item and form.
*/
$mos_option_panel = new_cmb2_box( array(
'id' => 'mosc_theme_options_page',
'title' => esc_html__( 'Theme Options', 'cmb2' ),
'parent_slug' => 'themes.php', // Make options page a submenu item of the themes menu.
'object_types' => array( 'options-page' ),
'option_key' => 'mosc_theme_options', // The option key and admin menu page slug.
'icon_url' => 'dashicons-palmtree', // Menu icon. Only applicable if 'parent_slug' is left empty.
) );
// Regular text field
$mos_option_panel->add_field( array(
'name' => __( 'Contact Form Heading', 'mosc' ),
'id' => 'mosc-contact-form-heading',
'type' => 'text',
'default' => __('Feel free to drop me a line', 'mosc'),
) );
}
then I've used this code for show my field value.
$mosc_contact_heading = get_option('mosc_theme_options');
if(!empty($mosc_contact_heading['mosc-contact-form-heading'])) {
echo esc_html($mosc_contact_heading['mosc-contact-form-heading']);
}
I've used this code to show my field value and working perfectly:
echo cmb2_get_option( '_key_options', 'text_text');
I'm creating a plugin for a custom post type. I want to add a custom template for it. But I'm not sure how to add it via the plugin.
How can I add a custom post type template via the plugin?
Please help!
You can simply create and assign custom page templates for your custom post type in your custom plugin.
Just create 2 template file - single-{post_type}.php and archive-{post_type}.php - in a new templates sub-directory of your plugin directory.
Then add some code as per below example in your main plugin:
/*
* Set Page templates for CPT "your_cpt"
*/
add_filter( 'template_include', 'my_plugin_templates' );
function my_plugin_templates( $template ) {
$post_type = 'your_cpt'; // Change this to the name of your custom post type!
if ( is_post_type_archive( $post_type ) && file_exists( plugin_dir_path(__DIR__) . "templates/archive-$post_type.php" ) ){
$template = plugin_dir_path(__DIR__) . "templates/archive-$post_type.php";
}
if ( is_singular( $post_type ) && file_exists( plugin_dir_path(__DIR__) . "templates/single-$post_type.php" ) ){
$template = plugin_dir_path(__DIR__) . "templates/single-$post_type.php";
}
return $template;
}
Hope this example would be helpful for you.
Cheers !!
Below is a complete (blank) plugin that I put together based on my previously posted answer. I loaded it in my theme (based on twentyfifteen) and it works. Together with the plugin, as-is, you would also need The following file structure
- schs-blank/css schs-blank/js schs-blank/images
schs-blank/archive-blank.php schs-blank/single-blank.php
schs-blank/schs-blank-edit-posts.php
schs-blank/schs-blank-template.php
It should not be too tricky to figure out what should be in the above files, but for starters just put "<h1>{filename}</h1>" to see where each page is called.
<?php
/*
Plugin Name: SCHS Blank Plugin
Plugin URI: http://www.southcoasthosting.com/schs-blank
Tags: jquery, flyout, vertical, menu, animated, css, navigation, widget, plugin, scroll
Description: Creates a widget to place a vertical menu which caters for many menu items.
Author: Gavin Simpson
Version: 0.1
Author URI: http://www.southcoasthosting.com
074 355 1881
*/
class schs_blank
{
protected $plugin_slug;
private static $instance;
protected $templates;
public static function get_instance()
{
if( null == self::$instance )
{
self::$instance = new schs_blank();
}
return self::$instance;
}
private function __construct()
{
$this->templates = array();
$page_template = dirname( __FILE__ ) . '/schs-blank-template.php';
$this->templates = array('schs-blank-template.php' => 'SCHS Blank Page Template','schs-blank-edit-posts.php'=>'Edit Blank Post Template');
if(!is_admin())
{
add_action( 'wp_blank', array('schs_blank', 'header') );
}
else
add_action( 'wp_blank', array('schs_blank', 'footer') );
add_filter('page_attributes_dropdown_pages_args',array( $this, 'register_project_templates' ));
add_filter('wp_insert_post_data', array( $this, 'register_project_templates' ));
add_filter( 'template_include', array($this,'schs_force_template' ));
add_filter('template_include', array( $this, 'view_project_template') );
add_action('admin_menu', array($this,'setup_blank_admin_menus'));
add_action( 'init', array($this,'blank_custom_post' ));
}
function schs_force_template($template)
{
if( is_archive( 'blank' ) )
{
$template = WP_PLUGIN_DIR .'/'. plugin_basename( dirname(__FILE__) ) .'/archive-blank.php';
}
if( is_singular( 'blank' ) )
{
$template = WP_PLUGIN_DIR .'/'. plugin_basename( dirname(__FILE__) ) .'/single-blank.php';
}
return $template;
}
function header(){
wp_enqueue_script('jquery');
wp_enqueue_style( 'blank-css', schs_blank::get_plugin_directory() . "/css/blank.css" );
wp_enqueue_script('schs_blank', schs_blank::get_plugin_directory() . '/js/schs-blank.js', array('jquery'));
}
function footer()
{
}
function get_plugin_directory(){
return WP_PLUGIN_URL . '/schs-blank';
}
function setup_blank_admin_menus()
{
add_menu_page('SCHS Blank Settings', 'SCHS Blank Settings', 'manage_options',
'SCHS_blank_settings', array($this,'SCHS_page_settings'));
add_submenu_page('SCHS_blank_settings',
'SCHS Page Elements', 'Blank Topics', 'manage_options',
'SCHS_blank_topics_settings', array($this,'SCHS_blank_topics_settings'));
}
function SCHS_page_settings()
{
?>
<div class="wrap">
<h2>There are no Blank options at this stage.</h2>
</div>
<?php
}
function SCHS_blank_topics_settings()
{
?>
<div id="blank_topics" class="wrap">
<h1>There are no blank topics at this stage</h1>
</div>
<?php
}
function blank_custom_post()
{
$labels = array(
'name' => _x( 'Blank', 'post type general name' ),
'singular_name' => _x( 'Topic', 'post type singular name' ),
'add_new' => _x( 'Add New', 'book' ),
'add_new_item' => __( 'Add New Blank Topic' ),
'edit_item' => __( 'Edit Blank Topic' ),
'new_item' => __( 'New Blank Topic' ),
'all_items' => __( 'All Blank Topics' ),
'view_item' => __( 'View Blank Topics' ),
'search_items' => __( 'Search Blank Topics' ),
'not_found' => __( 'No blank topics found' ),
'not_found_in_trash' => __( 'No blank topics found in the trash' ),
'parent_item_colon' => '',
'menu_name' => 'Blank'
);
$args = array(
'labels' => $labels,
'description' => 'Holds our blank topic specific data',
'public' => true,
'menu_position' => 5,
'supports' => array( 'title', 'editor'),
'has_archive' => true,
'menu_icon' => $this->get_plugin_directory().'/images/blank-icon.png',
);
register_post_type( 'blank', $args );
flush_rewrite_rules();
}
public function register_project_templates( $atts )
{
// Create the key used for the themes cache
$cache_key = 'page_templates-' . md5( get_theme_root() . '/' . get_stylesheet() );
// Retrieve the cache list.
// If it doesn't exist, or it's empty prepare an array
$templates = wp_get_theme()->get_page_templates();
if ( empty( $templates ) ) {
$templates = array();
}
// New cache, therefore remove the old one
wp_cache_delete( $cache_key , 'themes');
// Now add our template to the list of templates by merging our templates
// with the existing templates array from the cache.
$templates = array_merge( $templates, $this->templates );
// Add the modified cache to allow WordPress to pick it up for listing
// available templates
wp_cache_add( $cache_key, $templates, 'themes', 1800 );
return $atts;
}
/**
* Checks if the template is assigned to the page
*/
public function view_project_template( $template )
{
global $post;
if (!isset($this->templates[get_post_meta(
$post->ID, '_wp_page_template', true
)] ) ) {
return $template;
}
$file = plugin_dir_path(__FILE__). get_post_meta(
$post->ID, '_wp_page_template', true
);
// Just to be safe, we check if the file exist first
if( file_exists( $file ) )
{
return $file;
}
else
{
echo $file;
exit;
}
return $template;
}
}
add_action( 'plugins_loaded', array( 'schs_blank', 'get_instance' ) );
?>
I hope this helps a bit more.
This work for me, kindly try it, Thanks
Templates is loaded into cpt file, which was located at
custom_plugin -> app -> cpt -> cpt_article.php
Template is located
custom_plugin -> app -> templates
add_filter( 'single_template', 'load_my_custom_template', 99, 1 );
function load_custom_templates($single_template) {
global $post;
if ($post->post_type == 'article' ) {
$single_template = trailingslashit( plugin_dir_path( __FILE__ ) .'app/templates' ).'single_article.php';
}
return $single_template;
}
You create a template file in your plugin, e.g /templates/myposttype-page.php
Then add below code into your plugin.
Change 'myposttype' to your post type
$custom_post_type = 'myposttype';
add_filter("theme_{$custom_post_type}_templates", "add_{$custom_post_type}_template");
add_filter('single_template', "redirect_{$custom_post_type}_template");
function add_myposttype_template() {
$templates['myposttype-page.php'] = 'My type Template';
return $templates;
}
function redirect_myposttype_template ($template) {
if( is_page_template('myposttype-page.php') ){
$template = plugin_dir_path(__FILE__). 'templates/myposttype-page.php';
}
return $template;
}