继续回答这个问题:
Replacing WordPress menu functionality with a plugin
由于我很少使用WordPress(我用phpBB、myBB、Concrete5和定制PHP脚本做了很多工作,但我的WordPress经验仅限于一个或两个简单的网站),我觉得在这里我可能比花3个小时阅读文档更快得到答案。
我正在创建一个插件,用我自己的菜单替换WordPress菜单。到目前为止,这里是这个插件的代码(都在一个PHP文件中):
add_action(\'init\', \'DEMenu::init\');
class DEMenu {
public static function init() {
$DEMenu = new DEMenu();
load_plugin_textdomain (\'de-menu\', false, dirname( plugin_basename( __FILE__ ) ) . \'/languages/\');
/* Load CSS with wp_enqueue_style() */
// If in admin page, then load admin page stuff
if (is_admin()) {
add_action(\'admin_menu\', \'DEMenu::admin\');
}
// If not on admin page ...
else {
// Load plugin core - doesn\'t require a hook
$DEMenu->core();
}
}
public static function admin() {
add_options_page(\'DE Menu Options\', \'DE Menu\', \'manage_options\', \'de-menu\', \'DEMenu::options\');
// add_option(\'de_menu_maintenance\', \'off\');
}
public static function options() {
if (!current_user_can(\'manage_options\')) {
wp_die( __(\'You do not have sufficient permissions to access this page.\') );
}
echo \'<div class="wrap">\';
echo \'<p>Here is where the form would go if I actually had options.</p>\';
echo \'</div>\';
}
public static function core() {
/* Add support for various themes */
add_filter(\'wp_nav_menu\', \'DEMenu::display\');
/* If I need to add more actions/filters they will go here... I may enqueue CSS here, too */
}
public static function display() {
print "Let\'s see if this displays. I\'ll add some text to ctrl+F for later";
}
}
这主要是来自WordPress文档、插件开发教程和基本OOP实践的各种建议的结晶。
现在,我的任务是从仪表板>外观>菜单区域绘制菜单。如何访问此菜单对象(作为数组或其他可访问的数据类型),以便使用它?
我确实意识到完全无视wp_nav_menu()
如果我只想使用相同的菜单,那么输出,但是我想不出其他方法来实现我想要的。
编辑-
我一直在通读wp-includes/nav-menu-template.php
了解如何wp_nav_menu()
获取菜单项列表及其显示方式。我一直在尝试模拟此函数使用的方法,只是在多列结构中添加了一些细微的变化。以下是我目前掌握的情况:
public static function core() {
/* Add support for varoius themes */
add_filter(\'wp_nav_menu\', \'DEMenu::display\', 1);
/* If I need to add more actions/filters they will go here... I may enqueue CSS here, too */
}
public static function display( $args ) {
/* The following is blatantly ripped from nav-menu-template.php */
// *****************************************************************
/* Excluded for ease of reading - this is an exact copy of nav-menu-template.php */
// *****************************************************************
// Here we can invoke our custom walker without editing the theme
$args->walker = \'DEMenu_Walker\';
$items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args );
unset($sorted_menu_items);
// *****************************************************************
/* Excluded for ease of reading - this is an exact copy of nav-menu-template.php */
// *****************************************************************
// $nav_menu = apply_filters( \'wp_nav_menu\', $nav_menu, $args );
//
// if ( $args->echo )
// echo $nav_menu;
// else
// return $nav_menu;
// Rather than checking if we should echo the output, just return it.
// This is a filter, so the output will be echo\'d by the calling function
return $nav_menu;
}
之后(在DEMenu类之外):
class DEMenu_Walker Extends Walker_Nav_Menu {
function __construct() {
die("We made it to the constructor!");
}
}
但是,我遇到以下错误:
Warning: Attempt to assign property of non-object in /home/coupon/public_html/wp-content/plugins/DE-menu/index.php on line 146
该行号是指:
$args->walker = \'DEMenu_Walker\';
也许有一个更合理的解决方案,我已经仔细研究过了,但是从我所知道的情况来看,我需要一个自定义walker类(以及用于跟踪显示了多少项以及每列应该显示多少项的私有变量),这是使用自定义walker类而不编辑主题的唯一方法。然而,如果我要使用我目前正在研究的解决方案,那么我需要了解
$args
变量是非对象,当
wp_nav_menu()
显然,在函数的最开始处有以下代码行:
$args = (object) $args;
另一个编辑-
我解决了非对象问题。什么时候wp_nav_menu()
调用它正在调用的筛选器,如下所示:
$nav_menu = apply_filters( \'wp_nav_menu\', $nav_menu, $args );
我没有意识到这意味着它在传递两个论点。我对显示功能进行了如下修改:
public static function display( $nav_menu, $args ){
当然修改了
add_filter()
像这样打电话:
add_filter( \'wp_nav_menu\', \'DEMenu::display\', 1, 2 );
虽然现在我有各种各样有趣的新错误。
Fatal error: Using $this when not in object context in /home/coupon/public_html/wp-includes/class-wp-walker.php on line 185
请注意,我没有对WordPress core进行任何修改,所以我不明白
class-wp-walker.php
... 我也不明白为什么这个错误现在才出现。有什么想法吗?
最终编辑-
在以下人员的帮助下https://stackoverflow.com/questions/6862887/replacing-wordpress-core-functionality-with-a-plugin 我终于意识到我可以使用wp_nav_menu_args
筛选以通过我自己的walker类,而不复制wp_nav_menu()
作用我将使用此解决方案(解决此问题),尽管如上所述,我遇到了一个新问题,我的walker类导致其父类抛出致命错误。我将对此提出一个新问题,因为这是Walker类的问题,而不是访问菜单项或传递自定义Walker。
<小时>Task: 我需要每个子菜单(第二级或更低级别)分为5列(5个单独的<ul>
元素或<div>
围绕某些<li>
元素)。