Skip to content

Instantly share code, notes, and snippets.

@radist2s
Last active April 8, 2019 12:18
Show Gist options
  • Save radist2s/488a7cf3d90c9e9a75064d07e600d447 to your computer and use it in GitHub Desktop.
Save radist2s/488a7cf3d90c9e9a75064d07e600d447 to your computer and use it in GitHub Desktop.
Wordpress Menu BEM-style classes
<?php
/**
* Adds classes for menu link
* If menu container has classes [base-menu baseMenu]
* than links will get classes [base-menu--link baseMenuLink]
*/
add_filter('nav_menu_link_attributes', function ($atts, $item, $args, $depth)
{
$classes = explode(' ', $args->container_class ?: $args->menu_class);
$classes = array_map(function ($class_name_base)
{
$link_class_name = trim($class_name_base);
if (mb_strpos($link_class_name, '__') !== FALSE) // base class name with Modifier
{
return FALSE;
}
if (is_camelcase_string($link_class_name))
{
$link_class_name .= 'Link'; // JS class name
}
elseif ($link_class_name) // simple BEM class name
{
$link_class_name .= '--link';
}
return $link_class_name;
}, $classes);
$classes = array_filter($classes);
$atts['class'] = implode($classes, ' ');
return $atts;
}, 10, 4);
/**
* Adds classes for menu items
* If menu container has classes [base-menu baseMenu]
* than items will get classes [base-menu--item baseMenuItem]
* Additionally items will get classes [base-menu--item__current base-menu--item__has-children]
* if it will possible
*/
add_filter('nav_menu_css_class', function ($classes, $item, $args)
{
$classes_origin = $classes;
$classes_base = explode(' ', $args->container_class ?: $args->menu_class);
$classes = array_map(function ($class_name_base) use ($classes_origin)
{
$item_class_name = trim($class_name_base);
if (mb_strpos($item_class_name, '__') !== FALSE) // base class name with Modifier
{
return FALSE;
}
if (is_camelcase_string($item_class_name))
{
$item_class_name .= 'Item'; // JS class name
}
elseif ($item_class_name) // simple BEM class name
{
$item_class_name .= '--item';
$item_classes = [$item_class_name];
if (in_array('current-menu-item', $classes_origin) OR in_array('current-menu-parent', $classes_origin))
{
$item_classes[] = $item_class_name . '__current';
}
if (in_array('menu-item-has-children', $classes_origin))
{
$item_classes[] = $item_class_name . '__has-children';
}
$item_class_name = implode($item_classes, ' ');
}
return $item_class_name;
}, $classes_base);
$classes = array_filter($classes);
return $classes;
}, 10, 3);
function is_camelcase_string($subject)
{
return preg_match('~[A-Z][a-z]~u', $subject);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment