Views lets you control the HTML output based on post content. You can craft complex expressions that evaluate values of different custom fields.

On this page:

  1. Introduction to conditional output in Views
  2. Checking custom field values
  3. Checking for empty fields
  4. Checking other attributes
  5. Using custom functions or class methods
  6. Examples
  7. FAQ

1. Introduction

Views has a powerful tool to generate conditional output: the [wpv-if] shortcode. The basic syntax for this shortcode is the following:

[wpv-if evaluate="expression to evaluate"]This gets displayed when the evaluated expression is true[/wpv-if]

Let’s start with an example. I want to list todo items and strike-out items that are already completed.

Todos list with items striked

You can see what I’m actually trying to do is wrap the title with <del></del> tags.

To do this, we need to check which todos are complete and add these tags around their titles – when we output the View (obviously, we don’t mean to edit the title of the todo and add these tags to the database).

Edit the View, go to the Layout section and click to edit the Meta HTML.

Meta HTML editor with conditional output
Meta HTML editor with conditional output

This is the meta HTML segment that we used to produce the <del> tags around the title:

[wpv-if completed="wpcf-completed" evaluate="$completed = 1"]<del>[/wpv-if]
[wpv-post-title]
[wpv-if completed="wpcf-completed" evaluate="$completed = 1"]</del>[/wpv-if]

The wpv-if shortcodes are Views’ way of executing conditional logic inside Views and Content Templates. This is how it works:

[wpv-if

  arg1="FIELD1_NAME"
  arg2="FIELD2_NAME"
  arg3...

  evaluate="EXPRESSION USING ARG1, ARG2, ..."

  condition="true|false" debug="false|true"]
<conditional-HTML>
[/wpv-if]

The arguments can have any name that you choose. If you call the first argument ‘arg1′, you will use it as $arg1 in the evaluate expression.

The condition (default=true) indicates the expected value of the evaluation. You can use ‘false’ values to display the output when the evaluate function fails. This way, you can implement if/else logic.

The debug option lets you understand what’s going on. It will output the error code, in case there is a problem parsing the expression in the evaluate function.

The evaluate attribute lets you evaluate custom field values, shortcode outputs and even custom function results. Inside the evaluate expression, you can use any of the following:

  • Variables defined as parameters inside this [wpvv-if] shortcode to get a custom field value, starting with a dollar sign.
  • Integer and floating-point numbers.
  • Strings wrapped inside single quotes.
  • Math operators: +, -, *, /
  • Comparison operators: <, >, =, <=, >=, !=
  • Boolean operators: AND, OR, NOT
  • Nested expressions – several levels of parentheses
  • empty() function that checks for blank or non-existing fields
  • Custom functions or even existing WordPress functions.

2. Checking custom field values

You can set custom attributes in the [wpv-if] shortcode to get custom field values. Then, you can use this value in the evaluated expression by prefixing the attribute with a dollar sign:

[wpv-if arg_1="wpcf-my-field" evaluate="$arg_1 = 'my value'"]The field wpcf-my-field has a value of 'my value'[/wpv-if]

Please note: WordPress does not like hyphens or uppercase letters in shortcode attributes, so the custom attributes to get custom field values can not contain them. You should use underscores and lowecase instead.

3. Checking for empty fields

You can check for fields that are blank or that don’t exist using the empty function.

Testing if a field is blank or empty:

[wpv-if url="wpcf-url" evaluate="empty($url)"]No url given[/wpv-if]

Add the “NOT” operator (!) in front of the empty function to test if a field is “NOT” empty:

[wpv-if url="wpcf-url" evaluate="!empty($url)"]The url is: [types field="url"][/types][/wpv-if]

Checking if a parent exists

When using Types posts relationships, we store the parent of a given type in a field _wpcf_belongs_{parent-slug}_id. Assume we are displaying a Car post type that usually has a parent Maker post type. Each Car will store its Maker id in the field _wpcf_belongs_maker_id, and you can check if a Car has a Maker just using this code:

[wpv-if maker="_wpcf_belongs_maker_id" evaluate="empty($maker)"]This car has no maker[/wpv-if]

WordPress stores the featured image as a custom field called _thumbnail_id. You can test for this with code like this:

[wpv-if image="_thumbnail_id" evaluate="!empty($image)"]<div class="my_featured_image">
  [wpv-post-featured-image size="full"]
</div>[/wpv-if]

4. Checking other attributes

You can use other shortcodes in the evaluate expression. This allows you to use conditional logic on the output you get from those shortcodes:

[wpv-if evaluate="'[wpv-post-type]' = 'post'"]This is a Post![/wpv-if]

The [wpv-if] shortcode does this by first evaluating the output of the shortcode and then adding it to the evaluation function. By defauly, the following shortcodes can be used inside a [wpv-if] evaluate expression:

  • [wpv-post-***] shortcodes – shortcodes starting with wpv-post- that are used inside single posts or Views listing posts.
  • [wpv-taxonomy-***] shortcodes – shortcodes starting with wpv-taxonomy- that are used inside Views listing taxonomies.
  • [wpv-user] shortcodes – shortcodes that are used inside Vies listing users.
  • [wpv-current-user] – this shortcode displays information about the current visitor.

In addition, we support the following shortcodes from other plugins by default:

  • [types] shortcodes – shortcodes from the Types plugin, used to display custom fields for single posts or inside Views listing posts. It can also be used to check Types usermeta fields:
    [wpv-if evaluate="'[types usermeta="user-single-line"][/types]' != 'something'"]leave out a given value[/wpv-if]
    [wpv-if evaluate="'[types usermeta="user-single-line"][/types]' = ''"]check for an empty field[/wpv-if]
    
  • [wpml-string] shortcodes – shortcodes from the String Translation addon for WPML to register strings for translation.

Also, you can set your own shortcodes as third-party shortcode arguments in the Views settings page. Once you ad them, they will work inside [wpv-if] evaluation expressions:

Views - Third party shortcode arguments
Views – Third party shortcode arguments

Checking for Types checkboxes field

The Types checkboxes stores the state of multiple checkboxes in a custom field. Because of the way it stores the states you can’t use the empty function to check if any checkboxes are ticked. You should use the types shortcode and add it to the evaluate function instead and then compare the output with an empty string:

[wpv-if evaluate="'[types field='building-features' separator=''][/types]' != ''"]
    Building Features: [types field="building-features" separator=", "][/types]
[/wpv-if]

Checking for the current user data

Use the [wpv-current-user] shortcode to find the current user and display text based on who he is.

[wpv-if evaluate="'[wpv-current-user info="login"]' = 'bruce'"]Bruce is logged in[/wpv-if]

You can find a list of the available values for the info parameter in the wpv-current-user documentation.

Checking for taxonomy attributes

If your View is listing taxonomies, you can use [wpv-taxonomy-***] shortcodes to test if the taxonomy data matches the desired value:

[wpv-if evaluate="'[wpv-taxonomy-title]' = 'My tax'"]This taxonomy is My tax[/wpv-if]

You can find a list of existing [wpv-taxonomy-***] shortcodes in the Views shortcodes documentation.

5. Using custom functions or class methods

You can also use PHP functions or class methods inside the evaluated expression:

[wpv-if evaluate="my_func() = 'aloha'"]The function returns 'aloha'[/wpv-if]
[wpv-if evaluate="MyClass::my_method() = 'aloha'"]The class MyClass has a method my_method that returned 'aloha'[/wpv-if]

Before using a function inside a conditional, you need to register it for security reasons. Even WordPress functions need to be registered. To do so, visit the Views -> Settings page and simply add your function to the section Functions inside conditional evaluations:

Views - Functions inside conditional evaluations
Views – Functions inside conditional evaluations

You can pass parameters to your functions or class methods, as follows:

  • Strings, wrapped in single quotes: my_func('my_value_1', 'my_value_2', ...)
  • Numbers, not wrapped: my_func(1, 2, ...)
  • Booleans, not wrapped: my_func(true, false, ...)
  • Null, not wrapped: my_func(null, ...)

Important: by default, all the functions used inside evaluation expressions will be passed this two parameters:

  • The current query type. Defaults to ‘posts’. When used inside a View, this will be the kind of object being listed: ‘posts’, ‘taxonomy’ or ‘users’.
  • The current displayed object. Defaults to the current global post being displayed. When used inside a View, it will be the current object: for Views listing posts, the current post object; for Views listing taxonomies, the current term object; for Views listing users, the current user object.

This is important because you should always set the optional parameters for your functions when you use them inside [wpv-if] shortcodes. If you don’t set the optional parameters in your function, they will be passed as those described above, so it may have unexpected results.

When you compare what your functions return, you should follow this guidelines:

  • The function must return a string, a number or a boolean. If the function does not exist, or returns null, an array or an object, the evaluation will fail.
  • You can compare the returned value using the standard comparison functions: = != < > <= >=
  • If you expect the function to return a string, the value to check against should be wrapped in single quotes: evaluate="my_func() = 'my_value'"
  • If you expect the function to return a number, the value to check against can be wrapped in single quotes, but it’s not mandatory: evaluate="my_func() = 2" and evaluate="my_func() = '2'" will both work.
  • If you expect the function to return a boolean, the value to check agains should be 1 or ‘1’ for true and 0 or ‘0’ for false.
  • To check if your function is returning an empty value, ccompare it to an empty string: evaluate="my_func() = ''"

Also, you should remember this:

  • If the function does not exist, the evaluation will fail.
  • As said above, if you call a function without filling the optional parameters or your function has mandatory parameters that are not passed, you can get unexpected results including PHP notices and warnings.

Checking for empty post content

You could use the shortcode [wpv-post-body view_template=”None”] and compare it against an empty string, or use the empty() function, to check if a post has an empty content. However, using that shortcode triggers some WordPress filters, so even if the post has indeed an empty content it could return a non empty string. But you can use a custom function to check this.

First, place this in your functions.php file:

function wpv_if_post_has_content($type, $object) {
	$return = 0;
	if ( $type == 'posts' ) {
		if ( empty( $object->post_content ) ) {
			$return = 0;
		} else {
			$return = count($object->post_content);
		}
	}
	return $return;
}

We create a custom function that will take just the two default parameters being passed to functions inside the [wpv-if] shortcode. If what we are displaying is a post, we check directly the length of the $post->post_content.

Now, we just need to write our conditional. Note that we do ot pass any argument to our function: they will be passed by default:

[wpv-if evaluate="wpv_if_post_has_content() = 0"]This post has no content[/wpv-if]

Checking for a post taxonomy

You can use the [wpv-post-taxonomy] shortcode to test if the post has any taxonomy before trying to display it.

[wpv-if evaluate="'[wpv-post-taxonomy type="post_tag" separator="" format="text"]' != ''"]
    [wpv-post-taxonomy type="post_tag" separator=", " format="link" show="name" sort="none"]
[/wpv-if]

However, using this method you can not check if a post is in a specific taxonomy. To evaluate this, we are going to use a WordPress function: has_term. Note that we pass all the optional parameters to this function:

[wpv-if evaluate="has_term('Test', 'post_tag', null) = '1'"]This post has a Tag named Test[/wpv-if]

Check if a Types repeating field has an nth item

Sometimes, checking if a field is empty is not enough. You can store multiple values in a Types repeating field, and you might need to check if such a field has a number of values to show different layouts.

Imagine you are storing images in a repeating field, and you will display the first of them as a featured image. but the rest will be wrapped in a container div.secondary-image. In this case, you can not use a [wpv-for-each] shortcode, since it will render all the fields in the same way and you want to style the first differently. Also, a classic [wpv-if] shortcode won’y helpeither, because it can only check the emptyness of the overall field and not on a concrete index.

Luckily, Views has the answer. Place the following code in your functions.php file:

function prefix_check_repeating_field_index_exists($field_id, $index, $mode, $object) {
	global $wpcf;
	if ( isset( $wpcf ) && function_exists('types_get_field') && $mode == 'posts' ) {
		$field = types_get_field( $field_id );
		if ( types_is_repetitive( $field ) ) {
			$wpcf->repeater->set( $object->ID, $field );
			$_meta = $wpcf->repeater->_get_meta();
			$meta = $_meta['custom_order'];
			if ( count( $meta ) > $index ) {
				return 1;
			} else {
				return 0;
			}
		} else {
			return 0;
		}
	} else {
		return 0;
	}
}

Now, you can check for particular indexes within a repeating field. Just remember two things: use the Types field name (without the wpcf- prefix) and remember that the index starts on 0:

[wpv-if evaluate="prefix_check_repeating_field_index_exists('my-image',2) = 1"] The field has a value in the index 2, meaning the repeating field <code>my-image</code> holds at least three images[/wpv-if]

6. Examples

Evaluate the value of a string field

[wpv-if strfield="wpcf-somestrcustomfield" evaluate="$strfield = 'content'"]

Check for ages larger than 13 and color green

[wpv-if age="wpcf-age" color="wpcf-color" evaluate="($age > 13) AND ($color = 'green')"]

Display the correct contact details of Views consultants

<p>Location: [wpv-if location="wpcf-consultant-location" evaluate="!empty($location)"][types field="consultant-location" class="" style=""][/types][/wpv-if]
[wpv-if location="wpcf-consultant-location" evaluate="empty($location)"]The Internet[/wpv-if]</p>
<p>
<strong><a target="_blank" href="[types field="consultant-website" raw="true"][/types]">[types field="consultant-short-name" class="" style=""][/types]'s Website</a></strong>
[wpv-if phone="wpcf-consultant-phone" evaluate="!empty($phone)"] &nbsp; | &nbsp; Contact: [types field="consultant-phone"][/types][/wpv-if]
</p>

This code will display the contact information that we have. We check if the location field is populated (not empty). If so, we display it. Otherwise, we say The Internet. Then, for contact methods, we check if we have a phone number and display that field if it’s not empty.

7. Important Notes (got problems? read these first)

I. Field names must be the same as appear in the database

The name of the field that you enter in the wpv-if shortcode must be the actual name of the custom field in the database.

Types appends “wpcf-” to all field names, to distinguish them. If you’re using this logic on custom fields that were created originally by Types, remember to add this prefix.

For example, if you’ve created a cost field, Types will save it in the database as “wpcf-cost”, and you should use it like this:

[wpv-if cost_value="wpcf-cost" evaluate="$cost_value > 10"]Costs more than 10[/wpv-if]

Otherwise, if you’re applying conditional logic on custom fields that were created somehow else, you shouldn’t add this prefix.

II. Use only lowercase letters for variable names and avoid hyphens

This is not going to work, because the variable name uses uppercase characters or hyphens:

[wpv-if targetURL="wpcf-tgurl" evaluate="!empty($targetURL)"]
[wpv-if target-url="wpcf-tgurl" evaluate="!empty($target-url)"]

This works fine:

[wpv-if target_url="wpcf-tgurl" evaluate="!empty($target_url)"]