From redaxo-core
Manages REDAXO metainfo fields (cat_*, art_*, med_*): SELECT/RADIO/CHECKBOX params separators (| options, :key:label), SQL-query options, rex_metainfo_add_field idempotency, rex_navigation::addFilter. For adding fields, fixing dropdowns, idempotent scripts, category filtering.
npx claudepluginhub friendsofredaxo/claude-marketplace --plugin redaxo-coreThis skill uses the workspace's default tool permissions.
Metainfo fields extend the standard structure tables (`rex_article`, `rex_clang_article`, `rex_category`) with custom columns. They show up in the article/category/media edit forms in the backend and are read with `rex_article::getValue('art_<name>')`, `rex_category::getValue('cat_<name>')`, `rex_media::getValue('med_<name>')`.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Executes ctx7 CLI to fetch up-to-date library documentation, manage AI coding skills (install/search/generate/remove/suggest), and configure Context7 MCP. Useful for current API refs, skill handling, or agent setup.
Share bugs, ideas, or general feedback.
Metainfo fields extend the standard structure tables (rex_article, rex_clang_article, rex_category) with custom columns. They show up in the article/category/media edit forms in the backend and are read with rex_article::getValue('art_<name>'), rex_category::getValue('cat_<name>'), rex_media::getValue('med_<name>').
params separator gotcha (SELECT / RADIO / CHECKBOX)When defining metainfo SELECT/RADIO/CHECKBOX fields via rex_metainfo_add_field(...) (or via the backend "Meta Infos" UI), the params string uses two separators that are easy to confuse:
| separates options: separates a single option's key:labelA literal comma is part of the option string — it is not a separator.
// ✅ Correct — Yes/No dropdown with empty placeholder
$params = ':–|1:Ja';
// └┬┘ └┬─┘
// │ └── option 2: key=1, label="Ja"
// └────── option 1: key="", label="–"
// ✅ Correct — three options
$params = '1:Tag|2:Woche|3:Monat';
// ❌ Wrong — comma is treated as part of the label
$params = '|–,1|Ja'; // produces 3 broken options: "", "–,1", "Ja"
Source of truth: addons/metainfo/lib/handler/handler.php — the parser does explode('|', $params) then explode(':', $valueGroup, 2).
If params parses as a SELECT ... query, REDAXO loads options from the DB instead of treating it as a literal list. Useful for dynamic dropdowns:
$params = 'SELECT id, name FROM ' . rex::getTable('team_role') . ' ORDER BY name';
The first column becomes the option key, the second becomes the label.
rex_metainfo_add_field() only adds — it doesn't update an existing field. For setup scripts that should be safe to re-run:
$tableName = rex::getTable('metainfo_field');
$existing = rex_sql::factory()->getArray(
'SELECT id, params FROM ' . $tableName . ' WHERE name = :name',
['name' => 'cat_in_navi_top']
);
if (empty($existing)) {
rex_metainfo_add_field(
'cat_in_navi_top', // name
'In top navi', // label
7, // type_id (7 = SELECT)
':–|1:Ja', // params
'', // default
'', // validate
'', // restrictions
rex_metainfo_category_handler::PREFIX // category prefix
);
} elseif ($existing[0]['params'] !== ':–|1:Ja') {
// UPDATE the row directly to fix params on existing field
rex_sql::factory()
->setTable($tableName)
->setWhere(['id' => $existing[0]['id']])
->setValue('params', ':–|1:Ja')
->update();
}
rex_navigation has addFilter() for narrowing the rendered tree to categories matching a metainfo value:
$nav = rex_navigation::factory();
$nav->addFilter('cat_in_navi_top', 1, '='); // matches stored value '1'
$nav->get(0, 1, true, true);
addFilter does a strict == against $category->getValue('cat_in_navi_top') — so the empty option (key "") naturally filters out, only categories with value '1' pass through.
:–|) for the empty placeholder – the dropdown has no "blank" first option, so categories without a chosen value can't show "(none)".rex_metainfo_add_field() twice with the same name and expecting the second call to update – it silently no-ops if the field exists.params value that returns more than 2 columns – everything past the second column is ignored.addFilter('cat_x', 1) (no operator) when stored values are strings – 1 != '1' in some configurations. Pass the value as the same type as stored, or use = operator.be_manager_relation (via YForm) is more powerful for FK relationships. Reserve metainfo for simple, structure-page-level annotations.type_id | Field type |
|---|---|
| 1 | Text |
| 2 | Textarea |
| 3 | Legend (display only) |
| 4 | Select (single) |
| 5 | Radio |
| 6 | Checkbox |
| 7 | Select (with multiple support) |
| 8 | Date |
| 9 | Datetime |
| 10 | Time |
| 11 | REX_MEDIA_BUTTON |
| 12 | REX_MEDIALIST_BUTTON |
| 13 | REX_LINK_BUTTON |
| 14 | REX_LINKLIST_BUTTON |
Use rex_metainfo_table_expander::PREFIX for media metainfo and the matching constants for article/category/clang.