Skip to content

Instantly share code, notes, and snippets.

@zackpyle
Last active May 7, 2023 16:06
Show Gist options
  • Star 45 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save zackpyle/a5ac8b60f32c58e0f718df01d2992bb7 to your computer and use it in GitHub Desktop.
Save zackpyle/a5ac8b60f32c58e0f718df01d2992bb7 to your computer and use it in GitHub Desktop.
Best PHP/JS Snippets
This is a collection of my most used or most useful PHP and JS snippets
**Disclaimer, I didn't write most of these - I just curated them over the years**
<?php // ignore this line - only for styling
// Creates shortcode to pull specific address info out of an ACF Google Map Field
add_shortcode( 'acf_address' , function( $atts ) {
if (!function_exists('get_field') ) return '';
$atts = shortcode_atts( array( 'field' => false , 'sub' => 'address' ) , $atts, $shortcode = 'acf_address' );
if ($atts[ 'field' ] && $map = get_field( $atts[ 'field'] ) ) {
if ( isset( $map[ $atts['sub'] ] ) ) return $map[ $atts['sub'] ];
}
return '[ something went wrong ]';
} );
/*
[acf_address field="ACF_FIELD_NAME" sub="address"]
Subfields you can pull:
address
lat
lng
zoom
place_id
street_number
street_name
street_name_short
city
state
state_short
post_code
country
country_short
*/
<?php // ignore this line - only for styling
// Return ACF Number Fields Formatted with Commas on the Frontend
add_filter('acf/format_value/name=ACF_FIELD_NAME', 'acf_number_comma', 20, 3);
add_filter('acf/format_value/name=ANOTHER_ACF_FIELD_NAME', 'acf_number_comma_decimal', 20, 3);
// Without Decimal
function acf_number_comma($value, $post_id, $field) {
$value = number_format(floatval($value));
return $value;
}
// With Decimal
function acf_number_comma_decimal($value, $post_id, $field) {
$value = number_format(floatval($value), 2);
return $value;
}
//Use to convert all number fields
//add_filter('acf/format_value/type=number', 'acf_number_comma', 30, 3);
// ACF Repeater + Hide/Show jQuery
jQuery(document).ready(function($)
{
// Hide all expanded steps
$('.expandedstep').hide()
//Show expanded steps while in the builder
$('html.fl-builder-edit .expandedstep').show();
// When an expand step button is clicked
$('.expandstepbtn').on('click', function(e)
{
e.preventDefault();
// Change Text for Expand Button
var stepbtntxtchange = $('.expandedstep').is(':visible') ? 'Expand' : 'Collapse';
$(this).text(stepbtntxtchange);
// Toggle the next adjacent sibling
$(this).next('.expandedstep').slideToggle(250);
});
});
/* This is an ACF repeater HTML for Beaver Builder/Themer */
[wpbb-acf-repeater name='REPEATER_FIELD_NAME']
<div class="projectstep">
/* Always Displays */
[wpbb post:acf type='text' name='project_step']
/* Expands after button is clicked */
<button class="expandbtn">Expand</button>
<div class="expandedstep">
[wpbb post:acf type='text' name='expanded_project_step']
</div>
</div>
[/wpbb-acf-repeater]
<?php // ignore this line - only for styling
// Add an ACF field to your body class - useful for setting a style using CSS on a page via an ACF field
function add_acf_body_class($class) {
if (!function_exists('get_field')) return $class;
$value = get_field('your_acf_field');
$class[] = $value;
return $class;
}
add_filter('body_class', 'add_acf_body_class');
// same function but for acf checkboxes that returns an array of all options and adds all checked as classes
function add_acf_checkbox_field_body_class($classes) {
if (!function_exists('get_field')) return $classes;
$checked_options = get_field('your_acf_checkbox_field');
foreach($checked_options as $option) {
$classes[] = $option;
}
return $classes;
}
add_filter('body_class', 'add_acf_checkbox_field_body_class');
// Same But For Taxonomy Archives
// function add_bg_position_body_class_tax($class) {
// if (!function_exists('get_field')) return $class;
// $term = get_queried_object();
// $value = get_field('hero_background_image_position', $term);
// $class[] = $value;
// return $class;
// }
// add_filter('body_class', 'add_bg_position_body_class_tax');
// Turn Off Looping of Beaver Builder Background Vimeo Video
jQuery(window).on('load', function(){
var $ = jQuery,
$vimeoPlayer = $('#hero-row .fl-bg-video').data('VMPlayer');
$vimeoPlayer.setLoop(false);
});
<?php // ignore this line - only for styling
// Embed Beaver Builder shortcode into a text widget
add_filter('widget_text', 'do_shortcode');
<?php // ignore this line - only for styling
// Change CPT Title text
function change_default_title($title)
{
$screen = get_current_screen();
// For Meet the Team CPT
if ('team_member' == $screen->post_type)
{
$title = 'Team Member Name';
}
// For Testimonial CPT
elseif ('testimonial' == $screen->post_type)
{
$title = 'Name';
}
return $title;
}
add_filter('enter_title_here', 'change_default_title');
<?php // ignore this line - only for styling
// Change name of Beaver Builder to Page Builder
add_filter('gettext', 'change_bb_admin_text', 20, 3);
function change_bb_admin_text($translated_text, $text, $domain)
{
if ('fl-builder' == $domain)
{
switch ($translated_text)
{
case 'Beaver Builder':
$translated_text = __('Page Builder', $domain);
break;
}
}
return $translated_text;
}
<?php // ignore this line - only for styling
// Change the CPT meta box title to the Pod name
add_filter('pods_meta_default_box_title', 'gnt_pods_meta_title', 10, 5);
function gnt_pods_meta_title($title, $pod, $fields, $pod_type, $pod_name) {
if (!empty($fields)) {
$title = $pod['label'];
}
return $title;
}
<?php // ignore this line - only for styling
// Clear Cloudflare (when using CF's plugin) after ACF option page update
add_filter( 'cloudflare_purge_everything_actions' , function( $actions) {
return array_merge( $actions, [ 'acf/save_post' ]);
}, 10,1);
// Clear Breeze Cache after ACF option page update
add_action('acf/save_post', 'acf_clear_cache');
function acf_clear_cache( $post_id ) {
do_action('breeze_clear_all_cache');
}
// Force BB cache rebuild after ACF option page update
add_action( 'acf/save_post', function( $post_id ) {
FLBuilderModel::delete_asset_cache_for_all_posts();
});
<?php // ignore this line - only for styling
// Connect an ACF field called post_excerpt to save to WP excerpt field
add_action('save_post', 'custom_acf_excerpt_field', 50);
function custom_acf_excerpt_field()
{
global $post;
$post_id = ($post->ID); // Current post ID
$post_excerpt = get_field('post_excerpt', $post_id); // ACF field here
if (($post_id) and ($post_excerpt))
{
$post_array = array(
'ID' => $post_id,
'post_excerpt' => $post_excerpt
);
remove_action('save_post', 'custom_acf_excerpt_field', 50); // Unhook this function so it doesn't loop infinitely
wp_update_post($post_array);
add_action('save_post', 'custom_acf_excerpt_field', 50); // Re-hook this function
}
}
<?php // ignore this line - only for styling
// Simple Font Example
//Custom Font
function my_bb_custom_fonts($system_fonts)
{
$system_fonts['Forza Book'] = array(
'fallback' => 'Verdana, Arial, sans-serif',
'weights' => array(
'400',
) ,
);
return $system_fonts;
}
// Add Custom Font to Beaver Builder Theme Customizer
add_filter('fl_theme_system_fonts', 'my_bb_custom_fonts');
// Add Custom Font to Page Builder modules
add_filter('fl_builder_font_families_system', 'my_bb_custom_fonts');
// Complex Font Example
// Custom Font
function my_bb_custom_fonts($system_fonts)
{
$system_fonts['TT Prosto Sans Condensed'] = array(
'fallback' => 'Verdana, Arial, sans-serif',
'weights' => array(
'400',
'700',
) ,
);
$system_fonts['TT Prosto Sans Condensed Italic'] = array(
'fallback' => 'Verdana, Arial, sans-serif',
'weights' => array(
'400',
'700',
) ,
);
return $system_fonts;
}
// Add Custom Font to Beaver Builder Theme Customizer
add_filter('fl_theme_system_fonts', 'my_bb_custom_fonts');
// Add Custom Font to Page Builder modules
add_filter('fl_builder_font_families_system', 'my_bb_custom_fonts');
<?php // ignore this line - only for styling
// New Image Size
add_image_size( 'hero-image', '2000', '1500', false );
// Allow Beaver Builder modules to use custom image sizes
add_filter('image_size_names_choose', 'insert_custom_image_sizes');
function insert_custom_image_sizes($sizes) {
global $_wp_additional_image_sizes;
if (empty($_wp_additional_image_sizes)) {
return $sizes;
}
foreach ($_wp_additional_image_sizes as $id => $data) {
if (!isset($sizes[$id])) {
$sizes[$id] = ucfirst(str_replace('-', ' ', $id));
}
}
return $sizes;
}
<?php // ignore this line - only for styling
// Add custom taxonomy to body class of singular post
function add_taxonomy_to_single( $classes ) {
if ( is_single() ) {
global $post;
$my_terms = get_the_terms( $post->ID, 'insert_taxonomy_slug' );
if ( $my_terms && ! is_wp_error( $my_terms ) ) {
$classes[] = $my_terms[0]->slug;
}
}
return $classes;
}
add_filter( 'body_class', 'add_taxonomy_to_single' );
<?php // ignore this line - only for styling
// Disable All WooCommerce Styles and Scripts Except Shop Pages
add_action('wp_enqueue_scripts', 'dequeue_woocommerce_styles_scripts', 99);
function dequeue_woocommerce_styles_scripts()
{
if (function_exists('is_woocommerce'))
{
if (!is_woocommerce() && !is_cart() && !is_checkout())
{
# Styles
wp_dequeue_style('woocommerce-general');
wp_dequeue_style('woocommerce-layout');
wp_dequeue_style('woocommerce-smallscreen');
wp_dequeue_style('woocommerce_frontend_styles');
wp_dequeue_style('woocommerce_fancybox_styles');
wp_dequeue_style('woocommerce_chosen_styles');
wp_dequeue_style('woocommerce_prettyPhoto_css');
# Scripts
wp_dequeue_script('wc_price_slider');
wp_dequeue_script('wc-single-product');
wp_dequeue_script('wc-add-to-cart');
wp_dequeue_script('wc-cart-fragments');
wp_dequeue_script('wc-checkout');
wp_dequeue_script('wc-add-to-cart-variation');
wp_dequeue_script('wc-single-product');
wp_dequeue_script('wc-cart');
wp_dequeue_script('wc-chosen');
wp_dequeue_script('woocommerce');
wp_dequeue_script('prettyPhoto');
wp_dequeue_script('prettyPhoto-init');
wp_dequeue_script('jquery-blockui');
wp_dequeue_script('jquery-placeholder');
wp_dequeue_script('fancybox');
wp_dequeue_script('jqueryui');
}
}
}
<?php // ignore this line - only for styling
// Disable BB inline editing
add_filter( 'fl_inline_editing_enabled', '__return_false' );
<?php // ignore this line - only for styling
// Disable Full Screen WP Editor
if (is_admin()) {
function disable_editor_fullscreen_by_default() {
$script = "jQuery( window ).load(function() { const isFullscreenMode = wp.data.select( 'core/edit-post' ).isFeatureActive( 'fullscreenMode' ); if ( isFullscreenMode ) { wp.data.dispatch( 'core/edit-post' ).toggleFeature( 'fullscreenMode' ); } });";
wp_add_inline_script( 'wp-blocks', $script );
}
add_action( 'enqueue_block_editor_assets', 'disable_editor_fullscreen_by_default' );
}
<?php // ignore this line - only for styling
// Removes Empty Modules in Themer if field is empty
function check_field_connections($is_visible, $node)
{
if (isset($node
->settings
->connections))
{
foreach ($node
->settings->connections as $key => $connection)
{
if (!empty($connection) && empty($node
->settings
->$key))
{
return false;
}
}
}
return $is_visible;
}
add_filter('fl_builder_is_node_visible', 'check_field_connections', 10, 2);
// Set equal heights using jQuery
jQuery(document).ready(function ($) {
$.fn.equalHeights = function () {
var max_height = 0;
$(this).each(function () {
max_height = Math.max($(this).height(), max_height);
});
$(this).each(function () {
$(this).height(max_height);
});
};
$(".pp-infobox-description").equalHeights();
$(window).resize(function () {
$(".pp-infobox-description").equalHeights();
});
});
<?php // ignore this line - only for styling
// Get First Name (aka first word in page title) - I use this for Team CPTs when I need to use their first name
add_shortcode( 'first_name', 'get_first_name' );
function get_first_name() {
$title = get_the_title();
$full_name_seperate = explode( ' ', $title );
return $full_name_seperate[0];
}
<?php // ignore this line - only for styling
// Add WP user role as body class
add_filter('body_class','add_role_to_body');
function add_role_to_body($classes) {
$current_user = new WP_User(get_current_user_id());
$user_role = array_shift($current_user->roles);
$classes[] = 'role-'. $user_role;
return $classes;
}
// CSS to highlight images with missing alt tags
.role-administrator img[alt=""]:not([aria-hidden="true"]),
.role-administrator img:not([alt]):not([aria-hidden="true"])
{
outline: 4px magenta dashed !important;
outline-offset: -4px;
}
<?php // ignore this line - only for styling
// Limit WordPress Revisions to 10
add_filter( 'wp_revisions_to_keep', 'page_revision_limit', 10, 2 );
function page_revision_limit( $num, $post ) {
$num = 10;
return $num;
}
// Makes a BB Column clickable
// Pre-requisite: There must be an A Tag contained within the column element and a class of clickable-col for the column
jQuery(document).ready(function($) {
$("body:not(.fl-builder-edit) .clickable-col").css("cursor", "pointer");
$("body:not(.fl-builder-edit) .clickable-col").on("click", function(event) {
$(this)
.find("a")[0]
.click();
});
$("body:not(.fl-builder-edit) .clickable-col a").on("click", function(event) {
event.stopPropagation();
});
});
/* Set size of div and end with ellipse - Useful for making post grid content uniform */
.overflow-ellipse{
height: 50px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
<?php // ignore this line - only for styling
function add_slug_body_class( $classes ) {
global $post;
if ( isset( $post ) ) {
$classes[] = $post->post_type . '-' . $post->post_name;
}
return $classes;
}
add_filter( 'body_class', 'add_slug_body_class' );
<?php // ignore this line - only for styling
// Remove Custom Taxonomy Metabox from WP Sidebar
// example custom post type is "event"
// example custom taxonomy is "events-category"
function remove_default_event_category_metabox()
{
remove_meta_box('tagsdiv-events-category', 'event', 'side');
}
add_action('admin_menu', 'remove_default_event_category_metabox');
// 'tagsdiv-{taxonomyname}' - Custom tag taxonomies metabox
// '{taxonomyname}div' - used for hierarchical taxonomies metabox
// OR use this to remove all CPTUI metaboxes!
function edit_taxonomy_args($args, $tax_slug, $cptui_tax_args)
{
// Set to false for all taxonomies created with CPTUI.
$args['meta_box_cb'] = false;
return $args;
}
add_filter('cptui_pre_register_taxonomy', 'edit_taxonomy_args', 10, 3);
add_filter('rest_prepare_taxonomy', function ($response, $taxonomy, $request)
{
$context = !empty($request['context']) ? $request['context'] : 'view';
// Context is edit in the editor
if ($context === 'edit' && $taxonomy->meta_box_cb === false)
{
$data_response = $response->get_data();
$data_response['visibility']['show_ui'] = false;
$response->set_data($data_response);
}
return $response;
}
, 10, 3);
// Remove placeholder from Fluent Forms multiselect after selecting an item
jQuery(document).ready(function ($) {
$(".ff_has_multi_select").on("change", function (e) {
var selectedItem = $(this).siblings("input.choices__input");
selectedItem.attr("data-placeholder", selectedItem.attr("placeholder"));
if (e.target.options.length > 0) {
selectedItem.removeAttr("placeholder");
} else {
selectedItem.attr("placeholder", selectedItem.attr("data-placeholder"));
selectedItem.css("width", "fit-content");
}
});
});
<?php // ignore this line - only for styling
// Creates function post_remove for removing menu item
function post_remove (){
remove_menu_page('edit.php');
}
//Removes Posts from Admin Menu
add_action('admin_menu', 'post_remove');
//Remove query param from URL - useful after passing info via query param that you want to get rid of after using in js
history.replaceState(null, "", location.href.split("?")[0]);
// Swap Headers on Scroll in Beaver Builder/Beaver Themer
// JS for scrolled header
var header_a = document.querySelector('#header-row-a');
var header_b = document.querySelector('#header-row-b');
var posY = 0;
window.addEventListener('scroll', function(e) {
//how far down you scroll
if (this.pageYOffset > 855) {
if (this.pageYOffset > posY) {
//use the size of your header here
header_a.style.transform = 'translateY(-100px)';
header_b.style.transform = 'translateY(-100px)';
} else {
header_a.style.transform = 'translateY(0)';
header_b.style.transform = 'translateY(0)';
}
posY = this.pageYOffset;
}
});
// CSS for scrolled header
<style>
@media screen and (min-width: 769px) {
body:not(.fl-builder-edit) header.fl-builder-content {
position: fixed;
top: 0;
left: 0;
width: 100%;
/* Change to the size of your header */
height: 100px;
overflow: hidden;
z-index: 30000;
}
body:not(.fl-builder-edit) #header-row-a:not(.fl-builder-edit) {
display: flex;
align-items: center;
/* Change to the size of your header */
height: 100px;
}
body:not(.fl-builder-edit) .fl-row-content-wrap:not(.fl-builder-edit) {
width: 100%;
}
body:not(.fl-builder-edit) #header-row-a,
#header-row-b {
top: 0;
left: 0;
width: 100%;
transition: transform 0.4s ease-in-out, opacity 0.4s ease-in-out;
}
}
</style>
// Set slick slider to continuous scroll like a stock ticker
jQuery(document).ready(function ($) {
$('.continuous').slick({
speed: 9000,
autoplay: true,
autoplaySpeed: 0,
cssEase: 'linear',
slidesToShow: 1,
slidesToScroll: 1,
variableWidth: true,
});
});
// By default, videos continue to run even when not visible. This is using unnecessary CPU resources.
jQuery.fn.isInViewport = function() {
var elementTop = jQuery(this).offset().top;
var elementBottom = elementTop + jQuery(this).outerHeight();
var viewportTop = jQuery(window).scrollTop();
var viewportBottom = viewportTop + jQuery(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
function maybeStartStopVideo() {
if (jQuery('.fl-bg-video video, .fl-video video').length == 0)
return;
jQuery('.fl-bg-video, .fl-video').each(function() {
var video = jQuery(this).find('video')[0];
if (!video) return;
if (jQuery(this).isInViewport() && jQuery(this).is(':visible') && /* Tab active? */ !document.hidden) {
//console.log('start video');
video.play();
} else {
//console.log('stop video');
video.pause();
}
});
}
jQuery(window).on('visibilitychange', maybeStartStopVideo);
jQuery(document).ready(function() {
// Events would be nicer but I couldn't get to work them reliably
setInterval(maybeStartStopVideo, 1000);
})
// Stop Video on BS Modal Close
jQuery(document).ready(function($) {
$('.modal').on('hidden.bs.modal', function () {
new Vimeo.Player($(this).find('iframe')).pause();
});
});
//<!-- Modal -->
//<div class="modal fade" id="[wpbb post:slug]" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="true">
// <div class="modal-dialog modal-dialog-centered" role="document">
// <div class="modal-content">
// <div class="modal-header">
// <button type="button" class="close" data-dismiss="modal" aria-label="Close Video">
// <span aria-hidden="true">&times;</span>
// </button>
// </div>
// <div class="modal-body wrapcenter">
// <div style="padding:56.25% 0 0 0;position:relative;">
// <iframe loading="lazy" class="vimeo-video" src="https://player.vimeo.com/video/[wpbb post:acf type='number' name='video_vimeo_id']?title=0&byline=0&portrait=0&api=1&player_id=vimeoplayer&autopause=1&dnt=1" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen>
// </iframe>
// <script src="https://player.vimeo.com/api/player.js"></script>
// </div>
// </div>
// </div>
// </div>
//</div>
<?php // ignore this line - only for styling
// Add custom tab to Woo Product from ACF Field + conditionally display it if ACF field doesn't have content
function how_to_use_tab($tabs)
{
if (!function_exists('get_field'))
{
return $tabs; // you need to return $tabs always
}
$content = trim(get_field('how_to_use'));
if (!$content || empty($content))
{
return $tabs;
}
$tabs['key_ingredients'] = array(
'title' => 'How to Use',
'priority' => 10,
'callback' => 'sd_how_to_use_callback'
);
return $tabs;
}
function sd_how_to_use_callback()
{
echo get_field('how_to_use');
}
add_filter('woocommerce_product_tabs', 'how_to_use_tab');
<?php // ignore this line - only for styling
// Encourage Upsell to meet Free Shipping
add_action('woocommerce_before_cart', 'vs_free_shipping_cart_notice_zones');
function vs_free_shipping_cart_notice_zones()
{
global $woocommerce;
// Get Free Shipping Methods for Rest of the World Zone & populate array $min_amounts
$default_zone = new WC_Shipping_Zone(0);
$default_methods = $default_zone->get_shipping_methods();
foreach ($default_methods as $key => $value)
{
if ($value->id === "free_shipping")
{
if ($value->min_amount > 0) $min_amounts[] = $value->min_amount;
}
}
// Get Free Shipping Methods for all other ZONES & populate array $min_amounts
$delivery_zones = WC_Shipping_Zones::get_zones();
foreach ($delivery_zones as $key => $delivery_zone)
{
foreach ($delivery_zone['shipping_methods'] as $key => $value)
{
if ($value->id === "free_shipping")
{
if ($value->min_amount > 0) $min_amounts[] = $value->min_amount;
}
}
}
// Find lowest min_amount
if (is_array($min_amounts))
{
$min_amount = min($min_amounts);
// Get Cart Subtotal inc. Tax excl. Shipping
$current = WC()
->cart->subtotal;
// If Subtotal < Min Amount Echo Notice
// and add "Continue Shopping" button
if ($current < $min_amount)
{
$added_text = esc_html__('Get free shipping if you order ', 'woocommerce') . wc_price($min_amount - $current) . esc_html__(' more!', 'woocommerce');
$return_to = apply_filters('woocommerce_continue_shopping_redirect', wc_get_raw_referer() ? wp_validate_redirect(wc_get_raw_referer() , false) : wc_get_page_permalink('shop'));
$notice = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url($return_to) , esc_html__('Continue Shopping', 'woocommerce') , $added_text);
}
else
{
$notice = esc_html__('Congratulations, you qualify for free shipping!', 'woocommerce');
}
wc_print_notice($notice, 'notice');
}
}
<?php // ignore this line - only for styling
// Remove Free Shipping when using Coupon
function no_free_ship_with_coupon($packages)
{
$applied_coupons = WC()
->session
->get('applied_coupons', array());
if (!empty($applied_coupons))
{
$free_shipping_id = 'free_shipping:5';
unset($packages[0]['rates'][$free_shipping_id]);
}
return $packages;
}
add_filter('woocommerce_shipping_packages', 'no_free_ship_with_coupon');
// Hide Shipping when Free Available
function my_hide_shipping_when_free_is_available($rates)
{
$applied_coupons = WC()
->session
->get('applied_coupons', array());
if (empty($applied_coupons))
{
$free = array();
foreach ($rates as $rate_id => $rate)
{
if ('free_shipping' === $rate->method_id)
{
$free[$rate_id] = $rate;
break;
}
}
return !empty($free) ? $free : $rates;
}
else
{
return $rates;
}
}
add_filter('woocommerce_package_rates', 'my_hide_shipping_when_free_is_available');
<?php // ignore this line - only for styling
// adds wp role to admin body class
add_filter('admin_body_class', 'add_role_to_admin_body');
function add_role_to_admin_body($classes) {
global $current_user;
$user_role = array_shift($current_user->roles);
$classes = 'role-'. $user_role;
return $classes;
}
// adds wp role to frontend body class
add_filter('body_class','add_role_to_body');
function add_role_to_body($classes) {
$current_user = new WP_User(get_current_user_id());
$user_role = array_shift($current_user->roles);
$classes[] = 'role-'. $user_role;
return $classes;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment