Actually <option>
field doesn’t work with any CSS. So WordPress Developers/Designers did a simple yet nice trick for the nesting layout for <option>
fields.
Actually in your inspection you missed something there:
<select name="page_id" id="page_id">
<option value="1" class="level-0">Level 0</option>
<option value="2" class="level-1"> Level 1</option>
<option value="3" class="level-1"> Level 1</option>
<option value="4" class="level-2"> Level 2</option>
<option value="5" class="level-3"> Level 3</option>
<option value="6" class="level-2"> Level 2</option>
<option value="7" class="level-3"> Level 3</option>
</select>
Have you noted the population of
(HTML special character for spaces) there?
That is what creating the nesting look.
Let’s get the hand dirty
- In WordPress
wp-includes/
folder, open the filepost-template.php
. - Now find
wp_dropdown_pages(
, so that you can find the function showing the dropdown (Line #1016 in WP 4.3.1) - In that function you will see another function is functioning there:
walk_page_dropdown_tree(
, search for that one. (Line #1309 in WP 4.3.1) - In that function you will see a Walker Class is functioning there,
Walker_PageDropdown
, find that class now. (Line #1471 in WP 4.3.1) - In that class you will see a function named
start_el
, and within that function actually the trick is running.
Have you noticed that $pad
variable there?
$pad = str_repeat(' ', $depth * 3);
Passing the $depth
of the page, this str_repeat()
is actually populating the spaces (
) there. str_repeat()
is a PHP function that repeats a string for specified times. And it’s working simply multiplying
3 times to the $depth
. And that’s the trick.
Let’s do it
Now let us implement the similar thing in your case:
$_pages = get_pages( array( 'post_type'=> 'your_hierachical_cpt' ) );
<select name="my_field" id="my-field">
<?php foreach ($_pages as $_page) {
$depth = count( get_post_ancestors( $_page->ID ) ); //page_depth
$pad = str_repeat(' ', $depth * 3);
echo '<option value="'. $_page->ID .'" class="level-'. $depth .'">'. $pad . $_page->post_title .'</option>';
} ?>
</select>
We’re having all the pages in $_pages
, having each of their depth in $depth
, and then following that simple trick, in $pad
. And when showing <option>
s, we are showing the $depth
classes, and adding the $pad
variable just before options’ texts.
Yay! đ