Skip to content

Link Field

A combined URL and target control for collecting a complete link definition in one field.

Overview

The Link field renders a URL input paired with an open-in-new-tab toggle. It returns an associative array with url and target keys. Use it for call-to-action buttons, banner links, logo links, navigation items, or any other setting that needs both a URL and a target option collected together.

Field Registration

php

[
    'id'       => 'hero_button_link',
    'type'     => 'link',
    'title'    => __( 'Hero Button Link', 'your-textdomain' ),
    'subtitle' => __( 'URL and target for the primary hero CTA button', 'your-textdomain' ),
    'default'  => [
        'url'    => '',
        'text'   => '',
        'target' => '_self',
        'rel'    => '',
    ],
]

Field Options

OptionTypeRequiredDescription
idstringUnique field identifier — used as the option key
typestringMust be link
titlestringLabel shown above the field
subtitlestringSmaller descriptive text shown below the label
descstringHelp text shown below the link inputs
defaultarrayDefault values — see sub-options below
requiredarrayConditional logic rules — see Conditional Logic

Default Sub-options

KeyTypeDescription
urlstringThe link URL — e.g. 'https://example.com'
textstringThe link label text — e.g. 'Shop Now'
targetstringLink target — '_self' (same tab) or '_blank' (new tab)
relstringLink rel attribute — '' (none) or 'nofollow'

Return Value

Type: array

Returns an associative array with url, text, target and rel keys, or the default array if nothing has been saved yet.

php

$link = themeplus_get_option( 'hero_button_link', [] );
// Returns:
// [
//     'url'    => 'https://example.com/shop',  // string — the link URL
//     'text'   => 'Shop Now',                   // string — the link label text
//     'target' => '_blank',                     // string — '_self' or '_blank'
//     'rel'    => 'nofollow',                   // string — '' or 'nofollow'
// ]

Usage Examples

Basic link output

php

$link   = themeplus_get_option( 'hero_button_link', [] );
$url    = $link['url']    ?? '';
$text   = $link['text']   ?? __( 'Learn More', 'your-textdomain' );
$target = $link['target'] ?? '_self';
$rel    = $link['rel']    ?? '';

// Always add noopener noreferrer when opening in a new tab
$rel_attr = '_blank' === $target ? 'noopener noreferrer' : $rel;

if ( $url ) {
    echo '<a href="' . esc_url( $url ) . '" target="' . esc_attr( $target ) . '" rel="' . esc_attr( $rel_attr ) . '" class="btn btn--primary">';
    echo esc_html( $text );
    echo '</a>';
}

CTA button with label

php

// Config — link field stores both URL and label
[
    'id'      => 'cta_button',
    'type'    => 'link',
    'title'   => __( 'CTA Button', 'your-textdomain' ),
    'default' => [
        'url'    => '',
        'text'   => __( 'Get Started', 'your-textdomain' ),
        'target' => '_self',
        'rel'    => '',
    ],
],

php

// Template
$link   = themeplus_get_option( 'cta_button', [] );
$url    = $link['url']    ?? '';
$text   = $link['text']   ?? __( 'Get Started', 'your-textdomain' );
$target = $link['target'] ?? '_self';
$rel    = '_blank' === $target ? 'noopener noreferrer' : ( $link['rel'] ?? '' );

if ( $url ) {
    echo '<a href="' . esc_url( $url ) . '" target="' . esc_attr( $target ) . '" rel="' . esc_attr( $rel ) . '" class="btn">';
    echo esc_html( $text );
    echo '</a>';
}

Logo link

php

$logo_link = themeplus_get_option( 'logo_link', ['url' => home_url('/'), 'target' => '_self'] );

$url    = $logo_link['url']    ?? home_url('/');
$target = $logo_link['target'] ?? '_self';
$rel    = $target === '_blank' ? ' rel="noopener noreferrer"' : '';

echo '<a href="' . esc_url( $url ) . '" target="' . esc_attr( $target ) . '"' . $rel . ' class="site-logo">';
// logo image output here
echo '</a>';

Multiple CTA links

php

$primary   = themeplus_get_option( 'hero_primary_link',   ['url' => '', 'target' => '_self'] );
$secondary = themeplus_get_option( 'hero_secondary_link', ['url' => '', 'target' => '_self'] );

foreach ( [
    ['link' => $primary,   'label' => __('Get Started', 'your-textdomain'), 'class' => 'btn--primary'],
    ['link' => $secondary, 'label' => __('Learn More',  'your-textdomain'), 'class' => 'btn--secondary'],
] as $item ) {
    $url    = $item['link']['url']    ?? '';
    $target = $item['link']['target'] ?? '_self';

    if ( ! $url ) continue;

    $rel = $target === '_blank' ? ' rel="noopener noreferrer"' : '';
    echo '<a href="' . esc_url( $url ) . '" target="' . esc_attr( $target ) . '"' . $rel . ' class="btn ' . esc_attr( $item['class'] ) . '">';
    echo esc_html( $item['label'] );
    echo '</a>';
}

With a conditional field

php

[
    'id'      => 'enable_hero_cta',
    'type'    => 'toggle',
    'title'   => __('Enable Hero CTA Button', 'your-textdomain'),
    'default' => true,
],
[
    'id'       => 'hero_cta_label',
    'type'     => 'text',
    'title'    => __('Button Label', 'your-textdomain'),
    'default'  => __('Get Started', 'your-textdomain'),
    'required' => ['enable_hero_cta', '==', true],
],
[
    'id'       => 'hero_cta_link',
    'type'     => 'link',
    'title'    => __('Button Link', 'your-textdomain'),
    'default'  => ['url' => '', 'target' => '_self'],
    'required' => ['enable_hero_cta', '==', true],
],

Notes

  • When target is '_blank', always use 'noopener noreferrer' as the rel attribute regardless of the stored rel value — this prevents reverse tabnapping. The stored rel value ('' or 'nofollow') applies only when targetis '_self'.
  • The text key stores the link label — use it directly with esc_html() for the anchor text. A separate Text field for the button label is not needed.
  • Always escape URLs with esc_url() and check that url is non-empty before rendering the anchor.

On This Page