Token导航 LogoToken导航

Agent Skill · 开发

umbraco-validation-context(umbraco 验证上下文)

umbraco-validation-context 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

umbraco-validation-context 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 8,566。

总安装 3,105周安装 132GitHub Stars 23下载 1,088核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:umbraco-validation-context(umbraco 验证上下文)
来源仓库:https://github.com/umbraco/umbraco-cms-backoffice-skills
仓库路径:skills/umbraco-validation-context
安装命令:
npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-validation-context
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-validation-context

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理。通过 npx skills add 命令从指定 GitHub 仓库安装使用。

安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。umbraco-validation-context 属于开发类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/umbraco-validation-context

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

umbraco-validation-context 怎么安装?

在终端执行 npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-va…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

umbraco-validation-context 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

umbraco-validation-context 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

umbraco-validation-context 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

umbraco-validation-context 用的人多吗?

公开数据是累计安装 3,105 次,近一周安装 132 次,下载 1,088 次,GitHub 23 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

umbraco-validation-context 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
umbraco-validation-context

umbraco 验证上下文 · 本页

3,10523需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Umbraco Validation Context

What is it?

UmbValidationContext provides a centralized validation system for forms in the Umbraco backoffice. It manages validation messages using JSON Path notation, supports both client-side and server-side validation, and enables reactive error counting for tabs and sections. This is essential for multi-step forms, workspace editors, and any UI that requires comprehensive validation feedback.

Documentation

Always fetch the latest docs before implementing:

Reference Examples

The Umbraco source includes working examples:

Validation Context Dashboard: /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/validation-context/

This example demonstrates multi-tab form validation with error counting.

Custom Validation Workspace Context: /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/custom-validation-workspace-context/

This example shows workspace-level validation patterns.

Related Foundation Skills

  • State Management: For observing validation state changes

- Reference skill: umbraco-state-management

  • Context API: For consuming validation context

- Reference skill: umbraco-context-api

Workflow

  1. Fetch docs - Use WebFetch on the URLs above
  2. Ask questions - What fields? What validation rules? Multi-tab form?
  3. Generate files - Create form element with validation context
  4. Explain - Show what was created and how validation works

Basic Setup

import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import {
  UMB_VALIDATION_CONTEXT,
  umbBindToValidation,
  UmbValidationContext,
} from '@umbraco-cms/backoffice/validation';
import type { UmbValidationMessage } from '@umbraco-cms/backoffice/validation';

@customElement('my-validated-form')
export class MyValidatedFormElement extends UmbLitElement {
  // Create validation context for this component
  readonly validation = new UmbValidationContext(this);

  @state()
  private _name = '';

  @state()
  private _email = '';

  @state()
  private _messages?: UmbValidationMessage[];

  constructor() {
    super();

    // Observe all validation messages
    this.consumeContext(UMB_VALIDATION_CONTEXT, (validationContext) => {
      this.observe(
        validationContext?.messages.messages,
        (messages) => {
          this._messages = messages;
        },
        'observeValidationMessages'
      );
    });
  }

  override render() {
    return html`
      <uui-form>
        <form>
          <div>
            <label>Name</label>
            <uui-form-validation-message>
              <uui-input
                type="text"
                .value=${this._name}
                @input=${(e: InputEvent) => (this._name = (e.target as HTMLInputElement).value)}
                ${umbBindToValidation(this, '$.form.name', this._name)}
                required
              ></uui-input>
            </uui-form-validation-message>
          </div>

          <div>
            <label>Email</label>
            <uui-form-validation-message>
              <uui-input
                type="email"
                .value=${this._email}
                @input=${(e: InputEvent) => (this._email = (e.target as HTMLInputElement).value)}
                ${umbBindToValidation(this, '$.form.email', this._email)}
                required
              ></uui-input>
            </uui-form-validation-message>
          </div>

          <uui-button look="primary" @click=${this.#handleSave}>Save</uui-button>
        </form>
      </uui-form>

      <pre>${JSON.stringify(this._messages ?? [], null, 2)}</pre>
    `;
  }

  async #handleSave() {
    const isValid = await this.validation.validate();
    if (isValid) {
      // Form is valid, proceed with save
      console.log('Form is valid!');
    }
  }
}

Multi-Tab Form with Error Counting

import { html, customElement, state, when } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbValidationContext, umbBindToValidation } from '@umbraco-cms/backoffice/validation';

@customElement('my-tabbed-form')
export class MyTabbedFormElement extends UmbLitElement {
  readonly validation = new UmbValidationContext(this);

  @state() private _tab = '1';
  @state() private _totalErrors = 0;
  @state() private _tab1Errors = 0;
  @state() private _tab2Errors = 0;

  // Form fields
  @state() private _name = '';
  @state() private _email = '';
  @state() private _city = '';
  @state() private _country = '';

  constructor() {
    super();

    // Observe total errors
    this.observe(
      this.validation.messages.messagesOfPathAndDescendant('$.form'),
      (messages) => {
        this._totalErrors = [...new Set(messages.map((x) => x.path))].length;
      }
    );

    // Observe Tab 1 errors (using JSON Path prefix)
    this.observe(
      this.validation.messages.messagesOfPathAndDescendant('$.form.tab1'),
      (messages) => {
        this._tab1Errors = [...new Set(messages.map((x) => x.path))].length;
      }
    );

    // Observe Tab 2 errors
    this.observe(
      this.validation.messages.messagesOfPathAndDescendant('$.form.tab2'),
      (messages) => {
        this._tab2Errors = [...new Set(messages.map((x) => x.path))].length;
      }
    );
  }

  override render() {
    return html`
      <uui-box>
        <p>Total errors: ${this._totalErrors}</p>

        <uui-tab-group @click=${this.#onTabChange}>
          <uui-tab ?active=${this._tab === '1'} data-tab="1">
            Tab 1
            ${when(
              this._tab1Errors,
              () => html`<uui-badge color="danger">${this._tab1Errors}</uui-badge>`
            )}
          </uui-tab>
          <uui-tab ?active=${this._tab === '2'} data-tab="2">
            Tab 2
            ${when(
              this._tab2Errors,
              () => html`<uui-badge color="danger">${this._tab2Errors}</uui-badge>`
            )}
          </uui-tab>
        </uui-tab-group>

        ${when(this._tab === '1', () => this.#renderTab1())}
        ${when(this._tab === '2', () => this.#renderTab2())}

        <uui-button look="primary" @click=${this.#handleSave}>Save</uui-button>
      </uui-box>
    `;
  }

  #renderTab1() {
    return html`
      <uui-form>
        <form>
          <label>Name</label>
          <uui-form-validation-message>
            <uui-input
              .value=${this._name}
              @input=${(e: InputEvent) => (this._name = (e.target as HTMLInputElement).value)}
              ${umbBindToValidation(this, '$.form.tab1.name', this._name)}
              required
            ></uui-input>
          </uui-form-validation-message>

          <label>Email</label>
          <uui-form-validation-message>
            <uui-input
              type="email"
              .value=${this._email}
              @input=${(e: InputEvent) => (this._email = (e.target as HTMLInputElement).value)}
              ${umbBindToValidation(this, '$.form.tab1.email', this._email)}
              required
            ></uui-input>
          </uui-form-validation-message>
        </form>
      </uui-form>
    `;
  }

  #renderTab2() {
    return html`
      <uui-form>
        <form>
          <label>City</label>
          <uui-form-validation-message>
            <uui-input
              .value=${this._city}
              @input=${(e: InputEvent) => (this._city = (e.target as HTMLInputElement).value)}
              ${umbBindToValidation(this, '$.form.tab2.city', this._city)}
              required
            ></uui-input>
          </uui-form-validation-message>

          <label>Country</label>
          <uui-form-validation-message>
            <uui-input
              .value=${this._country}
              @input=${(e: InputEvent) => (this._country = (e.target as HTMLInputElement).value)}
              required
            ></uui-input>
          </uui-form-validation-message>
        </form>
      </uui-form>
    `;
  }

  #onTabChange(e: Event) {
    this._tab = (e.target as HTMLElement).getAttribute('data-tab') ?? '1';
  }

  async #handleSave() {
    const isValid = await this.validation.validate();
    if (!isValid) {
      console.log('Form has validation errors');
    }
  }
}

Server-Side Validation Errors

Add server validation errors after an API call:

async #handleSave() {
  // First validate client-side
  const isValid = await this.validation.validate();
  if (!isValid) return;

  try {
    // Call API
    const response = await this.#saveToServer();

    if (!response.ok) {
      // Add server validation errors
      const errors = await response.json();

      for (const error of errors.validationErrors) {
        this.validation.messages.addMessage(
          'server',                    // Source
          error.path,                  // JSON Path (e.g., '$.form.name')
          error.message,               // Error message
          crypto.randomUUID()          // Unique key
        );
      }
    }
  } catch (error) {
    console.error('Save failed:', error);
  }
}

Key APIs

UmbValidationContext

// Create context
const validation = new UmbValidationContext(this);

// Validate all bound fields
const isValid = await validation.validate();

// Access messages manager
validation.messages;

Validation Messages

// Add a message
validation.messages.addMessage(source, path, message, key);

// Remove messages by source
validation.messages.removeMessagesBySource('server');

// Observe messages for a path and descendants
this.observe(
  validation.messages.messagesOfPathAndDescendant('$.form.tab1'),
  (messages) => { /* handle messages */ }
);

// Observe all messages
this.observe(
  validation.messages.messages,
  (messages) => { /* handle all messages */ }
);

umbBindToValidation Directive

// Bind an input to validation
${umbBindToValidation(this, '$.form.fieldName', fieldValue)}

JSON Path Notation

Validation uses JSON Path to identify fields:

PathDescription
$.formRoot form object
$.form.nameName field
$.form.tab1.emailEmail field in tab1
$.form.items[0].valueFirst item's value
$.form.items[*].nameAll item names

Validation Message Interface

interface UmbValidationMessage {
  source: string;    // 'client' | 'server' | custom
  path: string;      // JSON Path
  message: string;   // Error message text
  key: string;       // Unique identifier
}

Best Practices

  1. Use JSON Path hierarchy - Organize paths by tab/section for easy error counting
  2. Wrap inputs - Use <uui-form-validation-message> around inputs
  3. Clear server errors - Remove old server errors before new validation
  4. Unique keys - Use crypto.randomUUID() for server error keys
  5. Observe specific paths - Use messagesOfPathAndDescendant for scoped error counts
  6. Show counts on tabs - Display error badges to guide users to problems

That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.

平台分布

Codex

39.27%
按下载量换算427

Claude

27.87%
按下载量换算303

Cursor

18.25%
按下载量换算199

Gemini CLI

8.96%
按下载量换算97

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills