Skip to main content
Documentation/Developers/APIs/Hooks Reference/Loops
Developers

Loops

The Post Loop Builder and
Term Loop Builder fire actions at each stage of a
loop, so a plugin can inject markup without editing the element. All of them receive
$actionData, an array whose propertiesData key holds the loop element's settings.

Post Loop Builder

oxygen_posts_loop_before_loop

Action, $actionData. Before the loop, when there are posts. All five take the same
argument — $actionData['propertiesData'] is the loop element's settings, so a handler can
tell one loop from another.

add_action('oxygen_posts_loop_before_loop', function ($actionData) {
    $query = $actionData['propertiesData']['content']['query']['query'] ?? null;

    echo '<p class="loop-intro">Fresh from the workshop</p>';
});

oxygen_posts_loop_before_post

Action, $actionData. Before each item's wrapper.

oxygen_posts_loop_after_post

Action, $actionData. After each item's wrapper.

oxygen_posts_loop_after_loop

Action, $actionData. After the loop.

oxygen_posts_loop_after_pagination

Action, $actionData. After pagination is output.

Term Loop Builder

The same five, with the same arguments and the same timing — the example above applies
unchanged.

oxygen_terms_loop_before_loop

Action, $actionData. Before the loop, when there are terms.

oxygen_terms_loop_before_term

Action, $actionData. Before each item's wrapper.

oxygen_terms_loop_after_term

Action, $actionData. After each item's wrapper.

oxygen_terms_loop_after_loop

Action, $actionData. After the loop.

oxygen_terms_loop_after_pagination

Action, $actionData. After pagination is output.

Either loop

These fire for both elements and carry the query itself.

oxygen_before_loop, oxygen_after_loop

Actions, $loop, $actionData. Around the whole loop, with the query object. $loop is a
WP_Query for a post loop and a term query for a term loop, so check before using
WP_Query-only properties.

add_action('oxygen_before_loop', function ($loop, $actionData) {
    if ($loop instanceof WP_Query) {
        printf('<p class="result-count">%d results</p>', (int) $loop->found_posts);
    }
}, 10, 2);

oxygen_before_loop_item, oxygen_after_loop_item

Actions, $object, $objectType, $actionData. Around each item, with the post or term
being rendered and which of the two it is — $objectType is post, term or field.

add_action('oxygen_before_loop_item', function ($object, $objectType, $actionData) {
    if ($objectType !== 'post') {
        return;
    }

    if (get_post_meta($object->ID, 'sponsored', true)) {
        echo '<span class="badge">Sponsored</span>';
    }
}, 10, 3);

Classes

oxygen_loop_classes

Filter, $wrapperClass, $actionData. The class list on the loop's wrapper, as a
space-separated string rather than an array. oxygen_loop_item_classes works the same way.

add_filter('oxygen_loop_classes', function ($classes, $actionData) {
    return $classes . ' my-plugin-loop';
}, 10, 2);

oxygen_loop_item_classes

Filter, $itemClasses, $object, $objectType, $actionData. The class list on each
item.