使用 Timber 添加 multi-level 菜单
Adding multi-level menu's with Timber
我对 Timber 不熟悉 - in-fact 这是我第一次听说它,但我正在帮助一家慈善机构摆脱困境。
我已经解决了大部分问题 - 除了让 sub-menu 正常工作。
将项目添加到 Wordpress 中的 sub-menu 位置时,它们会出现在主菜单的同一级别。
想知道是否有人可以帮助我吗?
下面是各种 "twigs" 的代码 - 但如果您也需要函数代码来帮忙,请告诉我。
menu.twig:
{% for item in menu %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% include "menu.twig" with {'menu': item.get_children} %}
</li>
{% endfor %}
{% endif %}
header.twig
<header class="header">
<div class="header__secondary">
<div class="container">
<div class="row">
<div class="col-xs-12">
<nav class="header__nav nav-secondary">
<ul class="nav-secondary__ul">
{% include "menu.twig" with {
'menu': menu.header_secondary.items,
'prefix': 'nav-secondary'
} %}
<li class="nav-secondary__li nav-secondary__li--cart">
<a class="nav-secondary__a cart-customlocation" href="{{ cart_url }}"></a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div class="header__primary">
{% block header %}
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-2">
<a href="/" class="header__logo">
<img src="{{ site.theme.link }}/dist/img/logo.jpg" alt="{{ site.name }} Logo">
</a>
</div>
<div class="col-xs-6 col-md-10">
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
'menu': menu.header_primary.items,
'prefix': 'nav'
} %}
</ul>
</nav>
<div class="hamburger hamburger--spring">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</header>
functions.php
<?php
/**
* Timber starter-theme
* https://github.com/timber/starter-theme
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
if ( ! class_exists( 'Timber' ) ) {
add_action( 'admin_notices', function() {
echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url( admin_url( 'plugins.php#timber' ) ) . '">' . esc_url( admin_url( 'plugins.php' ) ) . '</a></p></div>';
});
add_filter('template_include', function( $template ) {
return get_stylesheet_directory() . '/static/no-timber.html';
});
return;
}
Timber::$dirname = array('views');
Timber::$autoescape = false;
/**
* We're going to configure our theme inside of a subclass of Timber\Site
* You can move this to its own file and include here via php's include("MySite.php")
*/
class StarterSite extends Timber\Site {
/** Add timber support. */
public function __construct() {
add_action( 'after_setup_theme', array( $this, 'theme_supports' ) );
add_filter( 'timber_context', array( $this, 'add_to_context' ) );
add_filter( 'get_twig', array( $this, 'add_to_twig' ) );
add_action( 'init', array( $this, 'register_post_types' ) );
add_action( 'init', array( $this, 'register_taxonomies' ) );
add_action( 'wp_enqueue_scripts', [$this, 'load_scripts'] );
parent::__construct();
register_nav_menu('header-secondary', 'Header Secondary');
register_nav_menu('header-primary', 'Header Primary');
remove_action('woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0); // kill woo breadcrumbs
remove_action( 'woocommerce_before_shop_loop' , 'woocommerce_catalog_ordering', 30 ); // kill woo sorting
remove_action( 'woocommerce_before_shop_loop' , 'woocommerce_result_count', 20 ); // kill woo # results
add_filter( 'woocommerce_add_to_cart_fragments', [$this, 'woocommerce_header_add_to_cart_fragment']);
add_filter( 'woocommerce_get_image_size_gallery_thumbnail', function( $size ) {
return array(
'width' => 400,
'height' => 400,
'crop' => 0,
);
});
add_action( 'after_setup_theme', function() {
add_theme_support( 'woocommerce' );
} );
}
/** This is where you can register custom post types. */
public function register_post_types() {
$name = "adoption";
$singular = "Adoption";
$plural = "Adoptions";
$labels = array(
'name' => _x("$plural", 'en'),
'singular_name' => _x("$singular", 'en'),
'all_items' => "All $plural",
'add_new' => _x("Add New $singular", 'en'),
'add_new_item' => _x("Add New $singular", 'en'),
'edit_item' => _x("Edit $singular", 'en'),
'new_item' => _x("New $singular", 'en'),
'view_item' => _x("View $singular", 'en'),
'search_items' => _x("Search $plural", 'en'),
'not_found' => _x("No $singular found", 'en'),
'not_found_in_trash' => _x("No $singular found in Trash", 'en'),
'parent_item_colon' => _x("Parent $singular:", 'en'),
'menu_name' => _x("$plural", 'en'),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'description' => $plural,
'supports' => array(
'title',
'editor',
'thumbnail',
'revisions'
),
'taxonomies' => ['adoption_type'],
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 4,
'menu_icon' => 'dashicons-welcome-view-site',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'post'
);
register_post_type($name, $args);
$name = "event";
$singular = "Event";
$plural = "Events";
$labels = array(
'name' => _x("$plural", 'en'),
'singular_name' => _x("$singular", 'en'),
'all_items' => "All $plural",
'add_new' => _x("Add New $singular", 'en'),
'add_new_item' => _x("Add New $singular", 'en'),
'edit_item' => _x("Edit $singular", 'en'),
'new_item' => _x("New $singular", 'en'),
'view_item' => _x("View $singular", 'en'),
'search_items' => _x("Search $plural", 'en'),
'not_found' => _x("No $singular found", 'en'),
'not_found_in_trash' => _x("No $singular found in Trash", 'en'),
'parent_item_colon' => _x("Parent $singular:", 'en'),
'menu_name' => _x("$plural", 'en'),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'description' => $plural,
'supports' => array(
'title',
'editor',
'thumbnail',
'revisions'
),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 4,
'menu_icon' => 'dashicons-welcome-view-site',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'post'
);
register_post_type($name, $args);
if(function_exists('acf_add_options_page')) {
acf_add_options_page([
'page_title' => 'Theme Content',
'menu_title' => 'Theme Content',
'menu_slug' => 'theme-content',
'capability' => 'edit_posts',
'redirect' => false
]);
}
if(function_exists('acf_add_options_page')) {
acf_add_options_page([
'page_title' => 'Donation Settings',
'menu_title' => 'Donation Settings',
'menu_slug' => 'donation-settings',
'capability' => 'edit_posts',
'redirect' => false
]);
}
}
/** This is where you can register custom taxonomies. */
public function register_taxonomies() {
$labels = array(
'name' => 'Adoption Types',
'singular_name' => 'Adoption Type',
'menu_name' => 'Adoption Type'
);
$rewrite = array(
'slug' => 'adoptions',
'with_front' => true,
'hierarchical' => false,
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => false,
'rewrite' => $rewrite,
);
register_taxonomy( 'adoption_type', 'adoption', $args );
}
public function load_scripts() {
wp_enqueue_style( 'main', get_stylesheet_directory_uri() . '/dist/css/main.min.css' );
wp_enqueue_script('slick-js', get_stylesheet_directory_uri() . '/dist/js/plugins/slick.min.js', 'jquery', false, true);
wp_enqueue_script('main-js', get_stylesheet_directory_uri() . '/dist/js/main.js', ['jquery', 'slick-js'], false, true);
}
/** This is where you add some context
*
* @param string $context context['this'] Being the Twig's {{ this }}.
*/
public function add_to_context( $context ) {
$context['options'] = get_fields('options');
$context['menu']['header_primary'] = new Timber\Menu('header-primary');
$context['menu']['header_secondary'] = new Timber\Menu('header-secondary');
$context['shop_url'] = get_permalink(woocommerce_get_page_id('shop' ));
$context['site'] = $this;
if (get_the_ID()) {
// load page modules
require_once('src/modules.php');
}
return $context;
}
public function theme_supports() {
// 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' );
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5', array(
'comment-form',
'comment-list',
'gallery',
'caption',
)
);
/*
* Enable support for Post Formats.
*
* See: https://codex.wordpress.org/Post_Formats
*/
add_theme_support(
'post-formats', array(
'aside',
'image',
'video',
'quote',
'link',
'gallery',
'audio',
)
);
add_theme_support( 'menus' );
}
/** This Would return 'foo bar!'.
*
* @param string $text being 'foo', then returned 'foo bar!'.
*/
public function myfoo( $text ) {
$text .= ' bar!';
return $text;
}
/** This is where you can add your own functions to twig.
*
* @param string $twig get extension.
*/
public function add_to_twig( $twig ) {
$twig->addExtension( new Twig_Extension_StringLoader() );
$twig->addFilter( new Twig_SimpleFilter( 'myfoo', array( $this, 'myfoo' ) ) );
return $twig;
}
function woocommerce_header_add_to_cart_fragment( $fragments ) {
global $woocommerce;
ob_start();
?>
<a class="cart-customlocation" href="<?php echo $woocommerce->cart->get_cart_url(); ?>" title="<?php _e('View your shopping cart', 'woothemes'); ?>"><?php echo sprintf(_n('%d item', '%d items', $woocommerce->cart->cart_contents_count, 'woothemes'), $woocommerce->cart->cart_contents_count);?> - <?php echo $woocommerce->cart->get_cart_total(); ?></a>
<?php
$fragments['a.cart-customlocation'] = ob_get_clean();
return $fragments;
}
}
new StarterSite();
编辑:根据收到的反馈,menu.twig 代码如下 - 但是,现在不显示任何菜单:
{% if items|default(menu.items) %}
<ul>
{% for item in items|default(menu.items) %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% include "menu.twig" with {'menu': item.get_children} %}
</li>
{% endfor %}
</ul>
{% endif %}
编辑 2:下面是 header.twig 因为里面还有一些菜单内容...
<header class="header">
<div class="header__secondary">
<div class="container">
<div class="row">
<div class="col-xs-12">
<nav class="header__nav nav-secondary">
<ul class="nav-secondary__ul">
{% include "menu.twig" with {
'menu': menu.menu_header_secondary.items,
'prefix': 'nav-secondary'
} %}
<li class="nav-secondary__li nav-secondary__li--cart">
<a class="nav-secondary__a cart-customlocation" href="{{ cart_url }}"></a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div class="header__primary">
{% block header %}
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-2">
<a href="/" class="header__logo">
<img src="{{ site.theme.link }}/dist/img/logo.jpg" alt="{{ site.name }} Logo">
</a>
</div>
<div class="col-xs-6 col-md-10">
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
'menu': menu.menu_header_primary.items,
'prefix': 'nav'
} %}
</ul>
</nav>
<div class="hamburger hamburger--spring">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</header>
编辑 3 - @Gchtr 输入后的当前配置并获得正确的菜单以显示在正确的位置。仍然没有 sub-menus:
menu.twig:
{% set items = items|default(menu.items) %}
{% if items %}
<ul>
{% for item in items %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% if item.children %}
{% include "menu.twig" with { items: item.children } %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
header.twig:
<header class="header">
<div class="header__secondary">
<div class="container">
<div class="row">
<div class="col-xs-12">
<nav class="header__nav nav-secondary">
<ul class="nav-secondary__ul">
{% include "menu.twig" with {
'menu': menu_header_secondary,
'prefix': 'nav-secondary'
} %}
<li class="nav-secondary__li nav-secondary__li--cart">
<a class="nav-secondary__a cart-customlocation" href="{{ cart_url }}"></a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div class="header__primary">
{% block header %}
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-2">
<a href="/" class="header__logo">
<img src="{{ site.theme.link }}/dist/img/logo.jpg" alt="{{ site.name }} Logo">
</a>
</div>
<div class="col-xs-6 col-md-10">
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
'menu': menu_header_primary,
'prefix': 'nav'
} %}
</ul>
</nav>
<div class="hamburger hamburger--spring">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</header>
functions.php(Header 的片段而不是全部):
public function add_to_context( $context ) {
$context['options'] = get_fields('options');
$context['menu_header_primary'] = new Timber\Menu( 'header-primary' );
$context['menu_header_secondary'] = new Timber\Menu( 'header-secondary') ;
$context['shop_url'] = get_permalink(woocommerce_get_page_id('shop' ));
$context['site'] = $this;
您似乎缺少 <ul></ul>
包装器,或者您没有完整发布代码:
{% if menu %}
<ul>
{% for item in menu %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}">{{ item.title }}</a>
{% include "menu.twig" with {'items': item.children} %}
</li>
{% endfor %}
</ul>
{% endif %}
在 StarterSite
class 的 add_to_context()
方法中,您要像这样添加菜单:
$context['menu']['header_primary'] = new Timber\Menu('header-primary');
$context['menu']['header_secondary'] = new Timber\Menu('header-secondary');
当你现在想在你的 Twig 中使用访问 menu.items
时,那是行不通的,因为你不访问嵌套值。应该是menu.header_primary.items
。为了简化这一点,我将其更改为使用单独的上下文条目:
$context['menu_header_primary'] = new Timber\Menu( 'header-primary' );
$context['menu_header_secondary'] = new Timber\Menu( 'header-secondary') ;
然后,对于您的 Twig 文件,您将始终需要传递一个 menu
变量。
{% set items = items|default(menu.items) %}
{% if items %}
<ul>
{% for item in items %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% if item.children %}
{% include "menu.twig" with { items: item.children } %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
编辑
在您的 header.twig 中,您还需要从菜单包含中删除嵌套(menu_header_primary.items
而不是 menu.menu_header_primary.items
。否则,Timber 将选择它能找到的第一个菜单。
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
menu: menu_header_primary,
prefix: 'nav'
} %}
</ul>
</nav>
我对 Timber 不熟悉 - in-fact 这是我第一次听说它,但我正在帮助一家慈善机构摆脱困境。
我已经解决了大部分问题 - 除了让 sub-menu 正常工作。
将项目添加到 Wordpress 中的 sub-menu 位置时,它们会出现在主菜单的同一级别。
想知道是否有人可以帮助我吗?
下面是各种 "twigs" 的代码 - 但如果您也需要函数代码来帮忙,请告诉我。
menu.twig:
{% for item in menu %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% include "menu.twig" with {'menu': item.get_children} %}
</li>
{% endfor %}
{% endif %}
header.twig
<header class="header">
<div class="header__secondary">
<div class="container">
<div class="row">
<div class="col-xs-12">
<nav class="header__nav nav-secondary">
<ul class="nav-secondary__ul">
{% include "menu.twig" with {
'menu': menu.header_secondary.items,
'prefix': 'nav-secondary'
} %}
<li class="nav-secondary__li nav-secondary__li--cart">
<a class="nav-secondary__a cart-customlocation" href="{{ cart_url }}"></a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div class="header__primary">
{% block header %}
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-2">
<a href="/" class="header__logo">
<img src="{{ site.theme.link }}/dist/img/logo.jpg" alt="{{ site.name }} Logo">
</a>
</div>
<div class="col-xs-6 col-md-10">
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
'menu': menu.header_primary.items,
'prefix': 'nav'
} %}
</ul>
</nav>
<div class="hamburger hamburger--spring">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</header>
functions.php
<?php
/**
* Timber starter-theme
* https://github.com/timber/starter-theme
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
if ( ! class_exists( 'Timber' ) ) {
add_action( 'admin_notices', function() {
echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url( admin_url( 'plugins.php#timber' ) ) . '">' . esc_url( admin_url( 'plugins.php' ) ) . '</a></p></div>';
});
add_filter('template_include', function( $template ) {
return get_stylesheet_directory() . '/static/no-timber.html';
});
return;
}
Timber::$dirname = array('views');
Timber::$autoescape = false;
/**
* We're going to configure our theme inside of a subclass of Timber\Site
* You can move this to its own file and include here via php's include("MySite.php")
*/
class StarterSite extends Timber\Site {
/** Add timber support. */
public function __construct() {
add_action( 'after_setup_theme', array( $this, 'theme_supports' ) );
add_filter( 'timber_context', array( $this, 'add_to_context' ) );
add_filter( 'get_twig', array( $this, 'add_to_twig' ) );
add_action( 'init', array( $this, 'register_post_types' ) );
add_action( 'init', array( $this, 'register_taxonomies' ) );
add_action( 'wp_enqueue_scripts', [$this, 'load_scripts'] );
parent::__construct();
register_nav_menu('header-secondary', 'Header Secondary');
register_nav_menu('header-primary', 'Header Primary');
remove_action('woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0); // kill woo breadcrumbs
remove_action( 'woocommerce_before_shop_loop' , 'woocommerce_catalog_ordering', 30 ); // kill woo sorting
remove_action( 'woocommerce_before_shop_loop' , 'woocommerce_result_count', 20 ); // kill woo # results
add_filter( 'woocommerce_add_to_cart_fragments', [$this, 'woocommerce_header_add_to_cart_fragment']);
add_filter( 'woocommerce_get_image_size_gallery_thumbnail', function( $size ) {
return array(
'width' => 400,
'height' => 400,
'crop' => 0,
);
});
add_action( 'after_setup_theme', function() {
add_theme_support( 'woocommerce' );
} );
}
/** This is where you can register custom post types. */
public function register_post_types() {
$name = "adoption";
$singular = "Adoption";
$plural = "Adoptions";
$labels = array(
'name' => _x("$plural", 'en'),
'singular_name' => _x("$singular", 'en'),
'all_items' => "All $plural",
'add_new' => _x("Add New $singular", 'en'),
'add_new_item' => _x("Add New $singular", 'en'),
'edit_item' => _x("Edit $singular", 'en'),
'new_item' => _x("New $singular", 'en'),
'view_item' => _x("View $singular", 'en'),
'search_items' => _x("Search $plural", 'en'),
'not_found' => _x("No $singular found", 'en'),
'not_found_in_trash' => _x("No $singular found in Trash", 'en'),
'parent_item_colon' => _x("Parent $singular:", 'en'),
'menu_name' => _x("$plural", 'en'),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'description' => $plural,
'supports' => array(
'title',
'editor',
'thumbnail',
'revisions'
),
'taxonomies' => ['adoption_type'],
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 4,
'menu_icon' => 'dashicons-welcome-view-site',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'post'
);
register_post_type($name, $args);
$name = "event";
$singular = "Event";
$plural = "Events";
$labels = array(
'name' => _x("$plural", 'en'),
'singular_name' => _x("$singular", 'en'),
'all_items' => "All $plural",
'add_new' => _x("Add New $singular", 'en'),
'add_new_item' => _x("Add New $singular", 'en'),
'edit_item' => _x("Edit $singular", 'en'),
'new_item' => _x("New $singular", 'en'),
'view_item' => _x("View $singular", 'en'),
'search_items' => _x("Search $plural", 'en'),
'not_found' => _x("No $singular found", 'en'),
'not_found_in_trash' => _x("No $singular found in Trash", 'en'),
'parent_item_colon' => _x("Parent $singular:", 'en'),
'menu_name' => _x("$plural", 'en'),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'description' => $plural,
'supports' => array(
'title',
'editor',
'thumbnail',
'revisions'
),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 4,
'menu_icon' => 'dashicons-welcome-view-site',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'post'
);
register_post_type($name, $args);
if(function_exists('acf_add_options_page')) {
acf_add_options_page([
'page_title' => 'Theme Content',
'menu_title' => 'Theme Content',
'menu_slug' => 'theme-content',
'capability' => 'edit_posts',
'redirect' => false
]);
}
if(function_exists('acf_add_options_page')) {
acf_add_options_page([
'page_title' => 'Donation Settings',
'menu_title' => 'Donation Settings',
'menu_slug' => 'donation-settings',
'capability' => 'edit_posts',
'redirect' => false
]);
}
}
/** This is where you can register custom taxonomies. */
public function register_taxonomies() {
$labels = array(
'name' => 'Adoption Types',
'singular_name' => 'Adoption Type',
'menu_name' => 'Adoption Type'
);
$rewrite = array(
'slug' => 'adoptions',
'with_front' => true,
'hierarchical' => false,
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => false,
'rewrite' => $rewrite,
);
register_taxonomy( 'adoption_type', 'adoption', $args );
}
public function load_scripts() {
wp_enqueue_style( 'main', get_stylesheet_directory_uri() . '/dist/css/main.min.css' );
wp_enqueue_script('slick-js', get_stylesheet_directory_uri() . '/dist/js/plugins/slick.min.js', 'jquery', false, true);
wp_enqueue_script('main-js', get_stylesheet_directory_uri() . '/dist/js/main.js', ['jquery', 'slick-js'], false, true);
}
/** This is where you add some context
*
* @param string $context context['this'] Being the Twig's {{ this }}.
*/
public function add_to_context( $context ) {
$context['options'] = get_fields('options');
$context['menu']['header_primary'] = new Timber\Menu('header-primary');
$context['menu']['header_secondary'] = new Timber\Menu('header-secondary');
$context['shop_url'] = get_permalink(woocommerce_get_page_id('shop' ));
$context['site'] = $this;
if (get_the_ID()) {
// load page modules
require_once('src/modules.php');
}
return $context;
}
public function theme_supports() {
// 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' );
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5', array(
'comment-form',
'comment-list',
'gallery',
'caption',
)
);
/*
* Enable support for Post Formats.
*
* See: https://codex.wordpress.org/Post_Formats
*/
add_theme_support(
'post-formats', array(
'aside',
'image',
'video',
'quote',
'link',
'gallery',
'audio',
)
);
add_theme_support( 'menus' );
}
/** This Would return 'foo bar!'.
*
* @param string $text being 'foo', then returned 'foo bar!'.
*/
public function myfoo( $text ) {
$text .= ' bar!';
return $text;
}
/** This is where you can add your own functions to twig.
*
* @param string $twig get extension.
*/
public function add_to_twig( $twig ) {
$twig->addExtension( new Twig_Extension_StringLoader() );
$twig->addFilter( new Twig_SimpleFilter( 'myfoo', array( $this, 'myfoo' ) ) );
return $twig;
}
function woocommerce_header_add_to_cart_fragment( $fragments ) {
global $woocommerce;
ob_start();
?>
<a class="cart-customlocation" href="<?php echo $woocommerce->cart->get_cart_url(); ?>" title="<?php _e('View your shopping cart', 'woothemes'); ?>"><?php echo sprintf(_n('%d item', '%d items', $woocommerce->cart->cart_contents_count, 'woothemes'), $woocommerce->cart->cart_contents_count);?> - <?php echo $woocommerce->cart->get_cart_total(); ?></a>
<?php
$fragments['a.cart-customlocation'] = ob_get_clean();
return $fragments;
}
}
new StarterSite();
编辑:根据收到的反馈,menu.twig 代码如下 - 但是,现在不显示任何菜单:
{% if items|default(menu.items) %}
<ul>
{% for item in items|default(menu.items) %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% include "menu.twig" with {'menu': item.get_children} %}
</li>
{% endfor %}
</ul>
{% endif %}
编辑 2:下面是 header.twig 因为里面还有一些菜单内容...
<header class="header">
<div class="header__secondary">
<div class="container">
<div class="row">
<div class="col-xs-12">
<nav class="header__nav nav-secondary">
<ul class="nav-secondary__ul">
{% include "menu.twig" with {
'menu': menu.menu_header_secondary.items,
'prefix': 'nav-secondary'
} %}
<li class="nav-secondary__li nav-secondary__li--cart">
<a class="nav-secondary__a cart-customlocation" href="{{ cart_url }}"></a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div class="header__primary">
{% block header %}
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-2">
<a href="/" class="header__logo">
<img src="{{ site.theme.link }}/dist/img/logo.jpg" alt="{{ site.name }} Logo">
</a>
</div>
<div class="col-xs-6 col-md-10">
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
'menu': menu.menu_header_primary.items,
'prefix': 'nav'
} %}
</ul>
</nav>
<div class="hamburger hamburger--spring">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</header>
编辑 3 - @Gchtr 输入后的当前配置并获得正确的菜单以显示在正确的位置。仍然没有 sub-menus:
menu.twig:
{% set items = items|default(menu.items) %}
{% if items %}
<ul>
{% for item in items %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% if item.children %}
{% include "menu.twig" with { items: item.children } %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
header.twig:
<header class="header">
<div class="header__secondary">
<div class="container">
<div class="row">
<div class="col-xs-12">
<nav class="header__nav nav-secondary">
<ul class="nav-secondary__ul">
{% include "menu.twig" with {
'menu': menu_header_secondary,
'prefix': 'nav-secondary'
} %}
<li class="nav-secondary__li nav-secondary__li--cart">
<a class="nav-secondary__a cart-customlocation" href="{{ cart_url }}"></a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div class="header__primary">
{% block header %}
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-2">
<a href="/" class="header__logo">
<img src="{{ site.theme.link }}/dist/img/logo.jpg" alt="{{ site.name }} Logo">
</a>
</div>
<div class="col-xs-6 col-md-10">
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
'menu': menu_header_primary,
'prefix': 'nav'
} %}
</ul>
</nav>
<div class="hamburger hamburger--spring">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</header>
functions.php(Header 的片段而不是全部):
public function add_to_context( $context ) {
$context['options'] = get_fields('options');
$context['menu_header_primary'] = new Timber\Menu( 'header-primary' );
$context['menu_header_secondary'] = new Timber\Menu( 'header-secondary') ;
$context['shop_url'] = get_permalink(woocommerce_get_page_id('shop' ));
$context['site'] = $this;
您似乎缺少 <ul></ul>
包装器,或者您没有完整发布代码:
{% if menu %}
<ul>
{% for item in menu %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}">{{ item.title }}</a>
{% include "menu.twig" with {'items': item.children} %}
</li>
{% endfor %}
</ul>
{% endif %}
在 StarterSite
class 的 add_to_context()
方法中,您要像这样添加菜单:
$context['menu']['header_primary'] = new Timber\Menu('header-primary');
$context['menu']['header_secondary'] = new Timber\Menu('header-secondary');
当你现在想在你的 Twig 中使用访问 menu.items
时,那是行不通的,因为你不访问嵌套值。应该是menu.header_primary.items
。为了简化这一点,我将其更改为使用单独的上下文条目:
$context['menu_header_primary'] = new Timber\Menu( 'header-primary' );
$context['menu_header_secondary'] = new Timber\Menu( 'header-secondary') ;
然后,对于您的 Twig 文件,您将始终需要传递一个 menu
变量。
{% set items = items|default(menu.items) %}
{% if items %}
<ul>
{% for item in items %}
<li class="{{ prefix }}__li {{ item.classes | join(' ') }}">
<a class="{{ prefix }}__a" target="{{ item.target }}" href="{{ item.link }}"><span>{{ item.title }}</span></a>
{% if item.children %}
{% include "menu.twig" with { items: item.children } %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
编辑
在您的 header.twig 中,您还需要从菜单包含中删除嵌套(menu_header_primary.items
而不是 menu.menu_header_primary.items
。否则,Timber 将选择它能找到的第一个菜单。
<nav class="header__nav nav" role="navigation">
<ul class="nav__ul">
{% include "menu.twig" with {
menu: menu_header_primary,
prefix: 'nav'
} %}
</ul>
</nav>