Have a new project in the pipeline?

Proposal Form

Outputting Categories into a Select Field

11th June, 2020

A nice quick post for all you WordPress developers out there. This post is going to cover having a select field populated with a list of WP categories.

In our use case, we have a client who has a portfolio. This client creates a varied mixture of wonderful personalised arts and crafts. This client offers commissioned art, so communication is vital. We want the user to be able to clearly convey their desires, and we want our client to be able to easily digest the information they receive.

As the client we work with offers such a wide selection of custom art, a select field of “categories” which are used on the portfolio custom post type would be a great use of information which the user can use to select from.

A quick note before starting, when setting up the categories, it would be good to make the different types of art child categories. We have a category called “Portfolio”, this will be the parent to all types other of art categories available. This way we have a distinguishable way to identify them.

Initial Markup

Let’s start, by creating our initial select field markup:

<form class="form">
  <fieldgroup>

    <label class="form__label" for="category">Category</label>

    <select class="form__select" name="category">
      <option value="">Please select a category</option>
    </select>

  </fieldgroup>
</form>

Currently, our only option is our default value, this tells the user to select a category and passes no value. We want to start adding some of our categories, so let’s jump into some PHP:

<form class="form">
  <fieldgroup>

    <label class="form__label" for="category">Category</label>

    <select class="form__select" name="category">
        <option value="">Please select a category</option>

        <?php
        // Set the ID value of the parent Portfolio category
        $portfolio_parent_category_id = 4;

        // Set the arguments for the upcoming get_categories() call
        $args = [
          "child_of" => $portfolio_parent_category_id,
        ];

        // Get the categories
        // Standard WordPress function to get all categories in use. See the docs here.
        $categories = get_categories($args);
        ?>
    </select>

  </fieldgroup>
</form>

$categories now contains all the children categories of Portfolio with items assigned. If you want to include categories which have no items assigned, but is still a child of Portfolio add the following argument to the $args array 'hide_empty' => false.

With this set up, it’s time to loop over our array of categories:

<form class="form">
  <fieldgroup>

    <label class="form__label" for="category">Category</label>

    <select class="form__select" name="category">
      <option value="">Please select a category</option>

      <?php
      // Set the ID value of the parent Portfolio category
      $portfolio_parent_category_id = 4;

      // Set the arguments for the upcoming get_categories() call
      $args = [
        'child_of' => $portfolio_parent_category_id,
      ];

      // Get the categories
      $categories = get_categories($args);

      foreach ($categories as $category) {
        // Get the category name
        $name = $category->name;

        // Echo out the category as an option
        echo "<option value='$category->name'>$category->name</option>";
      }
      ?>
    </select>

  </fieldgroup>
</form>

This will now echo all the items into the select field, ready for a user to choose from.

Bonus Round

Let’s say you’re adding this to the output of a single portfolio item, chances are, the user will be looking to enquire about that category, so let’s set the currently showing category as the default option:

<form class="form">
  <fieldgroup>

    <label class="form__label" for="category">Category</label>

    <?php
    // Get the current category name
    $current_category_name = get_the_category()[0]->name;
    ?>

    <select class="form__select" name="category">
      <!-- Output the new default option here -->
      <option value="<?php echo $current_category_name; ?>">
        <?php echo $current_category_name; ?>
      </option>

      <?php
      // Set the ID value of the parent Portfolio category
      $portfolio_parent_category_id = 4;

      // Set the arguments for the upcoming get_categories() call
      $args = [
        'child_of' => $portfolio_parent_category_id,
      ];

      // Get the categories
      $categories = get_categories($args);

      foreach ($categories as $category) {
        // Get the category name
        $name = $category->name;

        // Check to see if category is the current posts category
        // We don't want current posts category to show as that's the default value of the select
        $is_current = $category->name === $current_category_name;

        // Echo out the category as an option if it's not the current category
        if (!$is_current) {
          echo "<option value='$category->name'>$category->name</option>";
        }
      }
      ?>
    </select>

  </fieldgroup>
</form>

There you have it, not the most everyday of tasks, but a nice little code block which can be extrapolated for other means.

If you’re running your own WordPress site and need a helping hand with any development, Tidy Design is here to help. Email us with any questions or head to our enquiry form.

Luke