Facebook Pixel not working on iOS mobile (Wordpress/Woocommerce) - wordpress
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).
Related
Set user registration date while creating account during Woocommerce order
When user completes the order, I want to save the user selected value as user registration date. I know it can be achived with this code: wp_update_user( [ 'ID' => $user_id, 'user_registered' => $user->user_registered, ] ); But how I can make it work with the rest of my code? How I can save this data as the registration date? I know how to save the order meta etc. but I've never did something like this. add_action( 'woocommerce_before_checkout_registration_form', 'custom_checkout_fields_before_billing_details', 20 ); function custom_checkout_fields_before_billing_details(){ $domain = 'woocommerce'; $checkout = WC()->checkout; echo '<div id="custom_checkout_field">'; woocommerce_form_field( '_custom_field_name', array( 'type' => 'text', 'label' => __('SELECT DATE', $domain ), 'placeholder' => __('DATE"', $domain ), 'class' => array('custom-field-class form-row-wide'), 'required' => false, // or false ), $checkout->get_value( '_custom_field_name' ) ); echo '</div>'; echo '<script>jQuery(document).ready(function( $ ) {$( "#_custom_field_name").datepicker();});</script>'; } // Save custom checkout fields the data to the order add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_meta', 10, 2 ); function custom_checkout_field_update_meta( $order, $data ){ if( isset($_POST['_custom_field_name']) && ! empty($_POST['_custom_field_name']) ) $order->update_meta_data( '_custom_field_name', sanitize_text_field( $_POST['_custom_field_name'] ) ); } add_action( 'wp_enqueue_scripts', 'enqueue_datepicker' ); function enqueue_datepicker() { if ( is_checkout() ) { // Load the datepicker script (pre-registered in WordPress). wp_enqueue_script( 'jquery-ui-datepicker' ); // You need styling for the date picker. For simplicity, I've linked to Google's hosted jQuery UI CSS. wp_register_style( 'jquery-ui', '//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css' ); wp_enqueue_style( 'jquery-ui' ); } }
buddypress pass an argument in a button
I use wordpress with the buddypress plugin. I am making a plugin in which I have a button. function bpbc_add_custom_buttons() { global $bp; $new_contact_button_args = array( 'id' => 'bpbc_new_contact', 'component' => 'members', 'must_be_logged_in' => true, 'block_self' => true, 'link_href' => esc_url( $bp->loggedin_user->domain . 'contacts/?id=' . $bp->displayed_user->id), 'link_text' => __( 'Add new contact' ), ); echo bp_get_button( $new_contact_button_args ); } add_action( 'bp_member_header_actions', 'bpbc_add_custom_buttons' ); This is what this button calls function contacts_screen() { add_action( 'bp_template_content', 'contacts_screen_content' ); bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) ); } function contacts_screen_content() { } I can't retrieve the argement id that is in my link 'link_href' => esc_url($bp->loggedin_user->domain. 'contacts/?id='. $bp->displayed_user->id) Thanks for your help
Try: function contacts_screen_content() { if ( isset( $_GET['id'] ) ) { echo 'id: ' . $_GET['id']; } }
Display custom checkout field value on admin order detail section in Woocommerce
Hello I'm trying to display the custom checkout field in the admin order details page. My Custom field is Delivery Option and it allows the user to pick the to pick a value from checkbox. I use the code below following the similar topics about this, but it seems something is wrong with my code. add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_additional_field', 20 ); function checkout_shipping_additional_field() { $domain = 'wocommerce'; $default = 'option 1'; echo '<tr class="additional-shipping-fields"><th>' . __('Delivery Time', $domain) . '</th><td>'; // Add a custom checkbox field woocommerce_form_field( 'custom_radio_field', array( 'type' => 'select', 'class' => array( 'form-row-wide' ), 'options' => array( 'option 1' => __('10:04 : 13:04 ', $domain), ), 'default' => $default, ), $default ); echo '</td></tr>'; } //update order meta add_action('woocommerce_checkout_update_order_meta', 'gon_update_order_meta_business_address'); function gon_update_order_meta_business_address( $order_id ) { if ($_POST['custom_radio_field']) update_post_meta( $order_id, 'Business Address?', esc_attr($_POST['custom_radio_field'])); } // Display field value on the admin order edit page add_action( 'woocommerce_admin_order_data_after_shipping_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 ); function custom_checkout_field_display_admin_order_meta( $order ){ $delivery_time = get_post_meta( $order->get_id(), 'Delivery Time', true ); if( ! empty( $delivery_time ) ) echo '<p><strong>'.__('Delivery Time', 'woocommerce').': </strong> ' . $delivery_time . '</p>'; }
There is some mistakes, so I have revisited your code. I have also replaced some hooks. Try the following: // HERE set your the options array for your select field. function delivery_time_options(){ $domain = 'woocommerce'; return array( '1' => __('10:04 : 13:04 ', $domain), '2' => __('14:04 : 16:04 ', $domain), // <== Added for testing ); } // Display a custom select field after shipping total line add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_additional_field', 20 ); function checkout_shipping_additional_field(){ $domain = 'woocommerce'; echo '<tr class="additional-shipping-fields"><th>' . __('Delivery Time', $domain) . '</th><td>'; // Add a custom select field woocommerce_form_field( 'delivery_time', array( 'type' => 'select', 'class' => array( 'form-row-wide' ), 'options' => delivery_time_options(), ), '' ); echo '</td></tr>'; } // Save custom field as order meta data add_action('woocommerce_checkout_create_order', 'save_custom_field_order_meta', 22, 2 ); function save_custom_field_order_meta( $order, $data ) { if ( isset($_POST['delivery_time']) ) { $options = delivery_time_options(); // Get select options array $option_key = esc_attr($_POST['delivery_time']); // The selected key $order->update_meta_data( '_delivery_time', $options[$option_key] ); // Save } } // Display a custom field value on the admin order edit page add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_custom_meta_data_in_backend_orders', 10, 1 ); function display_custom_meta_data_in_backend_orders( $order ){ $domain = 'woocommerce'; $delivery_time = $order->get_meta('_delivery_time'); if( ! empty( $delivery_time ) ) echo '<p><strong>'.__('Delivery Time', $domain).': </strong> ' . $delivery_time . '</p>'; } Code goes in function.php file of your active child theme (or active theme). Tested and works.
Based on #LoicTheAztec answer, if you want multiple fields without re-writing the functions for every field (DRY), you can use this class (by adding it to your functions.php): /** * Add a custom field to the woocommerce checkout page * https://stackoverflow.com/q/52098807/ */ class WOO_Add_Checkout_Field { public function __construct($options) { $this->field_name = $options['field_name']; $this->label = $options['label']; $this->placeholder = $options['placeholder']; $this->required = $options['required']; if ($this->field_name && $this->label && $this->placeholder) { add_action('woocommerce_after_order_notes', [$this, 'customise_checkout_field']); add_action('woocommerce_checkout_update_order_meta', [$this, 'custom_checkout_field_update_order_meta'], 10, 1); add_action('woocommerce_admin_order_data_after_billing_address', [$this, 'display_custom_field_on_order_edit_pages'], 10, 1); } else { die("Error in WOO_Add_Checkout_Field \$options: \n\n" . var_dump($options)); } } public function customise_checkout_field($checkout) { echo '<div id="customise_checkout_field">'; // echo '<h2>' . __('Heading') . '</h2>'; woocommerce_form_field($this->field_name, array( 'type' => 'text', 'class' => array( 'my-field-class form-row-wide' ), 'label' => $this->label, 'placeholder' => $this->placeholder, 'required' => $this->required, ), $checkout->get_value($this->field_name)); echo '</div>'; } public function custom_checkout_field_update_order_meta($order_id) { if (!empty($_POST[$this->field_name])) update_post_meta($order_id, $this->field_name, $_POST[$this->field_name]); else update_post_meta($order_id, $this->field_name, 0); } public function display_custom_field_on_order_edit_pages($order) { $field = $order->get_meta($this->field_name); if (!empty($field)) { echo '<p><strong style="display:block" title="' . $this->placeholder . '">' . $this->label . ': </strong><span>'; echo $field; echo '</span></p>'; } } } And use it as many times as you'd like: $my_custom_field_1 = new WOO_Add_Checkout_Field([ 'field_name' => 'my_custom_field_1', 'label' => __('My First Field'), 'placeholder' => __('Please write something in field 1...'), 'required' => false, ]); $my_custom_field_2 = new WOO_Add_Checkout_Field([ 'field_name' => 'my_custom_field_2', 'label' => __('My Second Field'), 'placeholder' => __('Please write something in field 2...'), 'required' => false, ]); $my_custom_field_3 = new WOO_Add_Checkout_Field([ 'field_name' => 'my_custom_field_3', 'label' => __('My Third Field'), 'placeholder' => __('Please write something in field 3...'), 'required' => false, ]); // and so on... Please note: The custom field will show up in admin area ONLY if it was not sent empty You can customize this code how you like
Add custom post type template via plugin
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; }
Twenty Ten child theme header image change error message: wordpress
I'm trying to change the header image width of my twenty ten child theme; when I add the following code to my child theme functions file: if ( !function_exists( 'child_theme_setup' ) ): function child_theme_setup() { define( 'HEADER_IMAGE_WIDTH', apply_filters( 'twentyten_header_image_width', 900 )); } I get the following error message: Parse error: syntax error, unexpected $end in... functions.php on line 132 Here is the whole code for the child functions file: <?php /** Tell WordPress to run child_theme_setup() when the 'after_setup_theme' hook is run. */ add_action( 'after_setup_theme', 'child_theme_setup' ); /** This function will hold our new calls and over-rides */ if ( !function_exists( 'child_theme_setup' ) ): function child_theme_setup() { /* We want a Second Navigation Bar right at the top This theme uses wp_nav_menu() in two locations. */ register_nav_menus( array( 'secondary' => __( 'Top Navigation', 'twentyten' ), ) ); // Add support for Featured Images if (function_exists('add_theme_support')) { add_theme_support('post-thumbnails'); add_image_size('index-categories', 160, 124, true); add_image_size('page-single', 350, 350, true); } function InsertFeaturedImage($content) { global $post; $original_content = $content; if ( current_theme_supports( 'post-thumbnails' ) ) { if ((is_page()) || (is_single())) { $content = the_post_thumbnail('page-single'); $content .= $original_content; } else { $content = the_post_thumbnail('index-categories'); $content .= $original_content; } } return $content; } add_filter( 'the_content', 'InsertFeaturedImage' ); // End Add support for Featured Images /* Remove the Twenty Ten registered sidebars */ remove_action( 'widgets_init', 'twentyten_widgets_init' ); /** Add our Widgetized Areas */ function child_widgets_init() { // Load our Widget Area Names and ID's into an Array $widgets = array ( array( "name" => "Sidebar Left One", "id" => "sidebar-left-one"), array( "name" => "Sidebar Left Two", "id" => "sidebar-left-two"), array( "name" => "Content Top", "id" => "content-top"), array( "name" => "Content Left", "id" => "content-left"), array( "name" => "Content Right", "id" => "content-right"), array( "name" => "Content Bottom", "id" => "content-bottom"), array( "name" => "Sidebar Right One", "id" => "sidebar-right-one"), array( "name" => "Sidebar Right Two", "id" => "sidebar-right-two"), array( "name" => "First Footer Widget", "id" => 'first-footer-widget-area'), array( "name" => "Second Footer Widget", "id" => 'second-footer-widget-area'), array( "name" => "Third Footer Widget", "id" => 'third-footer-widget-area'), array( "name" => "Fourth Footer Widget", "id" => 'fourth-footer-widget-area') ); /* Loop through the array and add our Widgetised areas */ foreach ($widgets as $widget) { register_sidebar( array( 'name' => __( $widget['name'], 'twentyten' ), 'id' => $widget['id'], 'description' => __( $widget['name'] .' Area', 'twentyten' ), 'before_widget' => '<li id="%1$s" class="widget-container %2$s">', 'after_widget' => '</li>', 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', ) ); } } /* Register sidebars by running twentyten_widgets_init() on the widgets_init hook. */ add_action( 'widgets_init', 'child_widgets_init' ); } /* This gets rid of the pagenavi css in your header */ add_action( 'wp_print_styles', 'my_deregister_styles', 100 ); function my_deregister_styles() { wp_deregister_style( 'wp-pagenavi' ); } /* Changes header image size */ add_action( 'after_setup_theme', 'child_theme_setup' ); if ( !function_exists( 'child_theme_setup' ) ): function child_theme_setup() { define( 'HEADER_IMAGE_WIDTH', apply_filters( 'twentyten_header_image_width', 900 )); } endif; I'm not sure what is ending incorrectly as it seems to work fine before I add the header code. I've tried entering the header code in different places and in different ways, to no avail.
I see two if (...): statements, but just one endif; Could that be the problem?