All skills
michtio avatar

/craft-plugins

@44a2800

Index and router for plugin-specific Craft CMS 5 guidance — configuration, Twig API, PHP API, migrations, deployment, and pitfalls for the plugins this pack documents. Triggers whenever a task names one of these plugins in ANY context (build, configure, style, render, query, import, migrate, deploy, cache, debug): Formie (forms, submissions, File Upload, form in a migration, notifications, translations), SEOmatic (meta, sitemaps, JSON-LD, SEO field), Blitz (static/page caching, purge), Feed Me (XML/JSON/CSV import), Imager-X (transforms, srcset, quick syntax, named transforms, Power Pack, pppicture, ppimg), ImageOptimize (OptimizedImages), CKEditor (rich text, nested entries), Sprig (reactive, htmx), Element API (JSON endpoints), Retour (redirects, 404s), Navigation (nav menus), Hyper (link field), Colour Swatches, Password Policy (HIBP), Typogrify, Cache Igniter, Knock Knock (staging password), Elements Panel (N+1 debug), Sherlock (security scan), Amazon SES (SES/SNS bounce), Embedded Assets (oEmbed), Timeloop (recurring dates), Vite (craft.vite.*, asset bundling), Warp (passwordless login, magic link, one-time code/OTP, passkeys, WebAuthn, craft.warp, member sessions). Also load for passwordless or magic-link auth with NO plugin named. Always load when a task names one of these plugins — read references/<plugin>.md first. Do NOT trigger for Craft core with no plugin named (craftcms), template architecture (craft-site), or content modeling (craft-content-modeling).

Use this Skill: https://skilld.dev/gh/michtio/craftcms-claude-skills/craft-plugins

This session only. Nothing lands on disk.

referenceshyper.md

≈1.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Hyper

Flexible link field type by Verbb. Supports entries, URLs, emails, phone numbers, assets, categories, users, and custom link types. Each link type has its own field layout for additional fields. #2 Top Paid plugin on the store — used in 5/6 projects.

verbb/hyper — $19

Documentation

When unsure about a Hyper feature, WebFetch the docs.

Common Pitfalls

  • Treating the field value as a single link when multipleLinks is enabled — a Hyper field returns a LinkCollection. For single-link fields it proxies to the first link via __get, but for multi-link fields you must iterate.
  • Using {{ link }} expecting text — string casting returns the URL, not the link text. Use link.getText() or link.linkText for the display text.
  • Not checking for empty links — editors can leave Hyper fields empty. Always null-check before accessing properties.
  • Hardcoding target="_blank" in templates — Hyper handles this via the newWindow property. Use link.getLinkAttributes() which includes target and rel automatically.
  • Forgetting that __call returns null for missing properties — Hyper intentionally doesn't throw errors for missing properties on links, making templates more forgiving. But this means typos in property names silently return null.

Link Types

Type Class Link Value
Entry links\Entry Craft entry element
URL links\Url Arbitrary URL
Email links\Email Email address → mailto:
Phone links\Phone Phone number → tel:
Asset links\Asset Craft asset element
Category links\Category Craft category element
User links\User Craft user element
Custom links\Custom Custom link type with custom fields
Site links\Site Link to a Craft site
Embed links\Embed oEmbed URL

Plugin-specific types: FormieForm, Product (Commerce), ShopifyProduct, CalendarEvent.

Twig API

Single Link Field

{% set link = entry.myLinkField %}

{% if link and link.getUrl() %}
    <a {{ link.getLinkAttributes({ class: 'btn btn-primary' }, true) }}>
        {{ link.getText() ?? 'Read more' }}
    </a>
{% endif %}

Key Properties and Methods

{{ link.getUrl() }}              {# Full URL (with urlSuffix if set) #}
{{ link.getText() }}             {# Link text (from linkText field) #}
{{ link.getLinkTitle() }}         {# Title attribute value #}
{{ link.getAriaLabel() }}        {# Aria-label value #}
{{ link.getClasses() }}          {# CSS classes string #}
{{ link.getNewWindow() }}        {# Boolean — opens in new tab? #}
{{ link.getCustomAttributes() }} {# Array of custom key/value attributes #}
{{ link.linkValue }}             {# Raw link value (URL, element ID, etc.) #}
{{ link.linkText }}              {# Raw link text #}
{{ link }}                       {# String cast → URL #}

getLinkAttributes() (Recommended)

Returns all link attributes as an array or rendered string — includes href, target, rel, class, title, aria-label, and custom attributes:

{# As rendered HTML attribute string #}
<a {{ link.getLinkAttributes({}, true) }}>{{ link.getText() }}</a>

{# With additional classes merged in #}
<a {{ link.getLinkAttributes({ class: 'btn' }, true) }}>{{ link.getText() }}</a>

{# As array for manual control #}
{% set attrs = link.getLinkAttributes() %}
<a href="{{ attrs.href }}" class="{{ attrs.class ?? '' }}">
    {{ link.getText() }}
</a>

Multiple Links Field

{% for link in entry.myLinksField %}
    {% if link.getUrl() %}
        <a {{ link.getLinkAttributes({ class: 'nav-link' }, true) }}>
            {{ link.getText() }}
        </a>
    {% endif %}
{% endfor %}

Element Link — Accessing the Linked Element

For Entry, Asset, Category, and User link types:

{% set link = entry.myLinkField %}
{% if link.getElement() %}
    {# Access the linked entry/asset/category directly #}
    {{ link.getElement().title }}
    {{ link.getElement().url }}
{% endif %}

Checking Link Type

link.type (from getType()) returns the link's fully-qualified class name, not a short string — so compare against the FQCN. Backslashes must be escaped in Twig single-quoted strings:

{% if link.type == 'verbb\\hyper\\links\\Entry' %}
    {# Entry-specific rendering #}
{% elseif link.type == 'verbb\\hyper\\links\\Url' %}
    {# External URL rendering #}
{% endif %}

Often cleaner to branch on element presence instead of the type string:

{% if link.getElement() %}
    {# Element link (Entry, Asset, Category, User) #}
{% elseif link.getUrl() %}
    {# URL or other non-element link #}
{% endif %}

Integration with Button Atom

Hyper pairs naturally with the button atom pattern. The link field provides URL, text, target, and aria-label — the atom handles rendering:

{# Pass Hyper link data to button atom #}
{% if link and link.getUrl() %}
    {% include '_atoms/button' with {
        url: link.getUrl(),
        label: link.getText() ?? 'Read more',
        ariaLabel: link.getAriaLabel() ?? null,
        newWindow: link.getNewWindow() ?? false,
    } only %}
{% endif %}

GraphQL

Hyper fields expose link data via GraphQL with type-specific fields for each configured link type.

Pair With

  • Colour Swatches — combine link + colour for themed CTAs

Source: SKILL.md on GitHub

No alerts16d3 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The 'craft-plugins' skill is a technical reference and router for Craft CMS 5 plugins. It provides guidance on configuration, Twig and PHP APIs, and best practices for popular extensions in the Craft ecosystem. The skill consists of documentation files that describe legitimate plugin behaviors and does not contain any malicious code, obfuscation, or security vulnerabilities.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

Signed by skilld at 44a2800. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated last month

README badge

README badge for michtio/craftcms-claude-skills/craft-plugins