Make WordPress Core

Opened 4 years ago

Last modified 3 months ago

#14041 reopened enhancement

Ensure a 'has_children' parameter is given to start_el

Reported by: jaapjanfrans Owned by:
Milestone: Future Release Priority: normal
Severity: minor Version: 3.0
Component: General Keywords: has-patch needs-testing
Focuses: template Cc:


In the current display_element function of the Walker class, a 'has_children' argument is only added if args[0] is an array.

I'm not quite sure why this is the case. Wouldn't it be easier if a has_children argument is always added and passed on on to the callback functions like start_el?

i've currently modified a custom walker to do it like this:

		//display this element
		if ( is_array( $args[0] ) )
			$args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
		$cb_args = array_merge( array(&$output, $element, $depth), $args);
		$cb_args['has_children'] = ! empty( $children_elements[$element->$id_field] );

But recon it can be done in a cleaner way.

Attachments (1)

has_children.diff (2.1 KB) - added by scribu 4 years ago.
Set flag on Walker object

Download all attachments as: .zip

Change History (11)

comment:1 scribu4 years ago

  • Keywords reporter-feedback added; has children walker has_children removed

Could you please point to the file and line number where has_children is set?

comment:2 jaapjanfrans4 years ago


file '/wp-includes/classes.php' on line number 854

comment:3 follow-up: scribu4 years ago

  • Keywords reporter-feedback removed
  • Milestone Unassigned deleted
  • Resolution set to invalid
  • Status changed from new to closed

First of all, call_user_func_array() only accepts a numeric array, so $cb_argshas_children? wouldn't work.

Secondly, it checks if $args[0] is an array so that start_el() can be both:

start_el($arg1 = 'foo', $arg2 = 'bar', ...)


start_el($args = array())

Anyway, it's just a convenience. You can do the check yourself, since you have access to $children_elements.

comment:4 in reply to: ↑ 3 jaapjanfrans4 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

I see your point, but it would still be nice if the start_el function could get this argument passed on by default, because now it only knows of this argument if the $args object passed to display_element is an array.. or am I missing something something there? I mean, $children_elements is not available to start_el in some way is it?

for now I resorted to adding the has_children argument to the $args object if it is an object (in display_element):

		//display this element
		if ( is_array( $args[0] ) )
			$args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
			$args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
		$cb_args = array_merge( array(&$output, $element, $depth), $args);

scribu4 years ago

Set flag on Walker object

comment:5 follow-up: scribu4 years ago

  • Component changed from General to Template
  • Milestone set to 3.1

You're right, start_el() doesn't have access to $children_elements.

Instead of altering $cb_args, a better solution would be to set a flag on the Walker object instead. See has_children.diff

You could then do:

function start_el() {
  if ( $this->has_children ) {
    // etc.

comment:6 in reply to: ↑ 5 jaapjanfrans4 years ago

Nice, thanks!

comment:7 scribu4 years ago

  • Keywords has-patch needs-testing added

comment:8 scribu4 years ago

Related: #14102

comment:9 nacin3 years ago

  • Milestone changed from Awaiting Triage to Future Release

comment:10 nacin3 months ago

  • Component changed from Template to General
  • Focuses template added
Note: See TracTickets for help on using tickets.