
Reactions snippet
Renders an interactive reaction block with counters. Works on any MODX object: resource, miniShop3 product, Tickets comment.
Parameters
| Parameter | Default | Description |
|---|---|---|
set | from reactions_default_set | Reaction set key (updown, github, full, or custom) |
types | (empty) | Comma-separated type name subset (intersection with the set). For full, otherwise uses reactions_full_types |
layout | auto | auto — picker if more than 3 types, otherwise bar. picker — chips + popover. bar — all buttons in a row |
class | modResource | Object class_key in xPDO |
object | current resource ID | Object ID |
context | current context key | MODX context (web, mgr, etc.) |
tpl | tpl.Reactions | Chunk for one reaction button |
tplOuter | tpl.Reactions.outer | Outer wrapper chunk |
toPlaceholder | (empty) | Placeholder name instead of direct output |
Built-in types and sets
All preset types (name → emoji). Names are what you pass to &types= and reactions_full_types.
name | Emoji | updown | github | full |
|---|---|---|---|---|
like | 👍 | ✓ | ✓ | ✓ |
dislike | 👎 | ✓ | ✓ | ✓ |
love | ❤️ | ✓ | ✓ | |
funny | 😂 | ✓ | ✓ | |
wow | 😮 | ✓ | ✓ | |
sad | 😢 | ✓ | ✓ | |
angry | 😡 | ✓ | ✓ | |
hooray | 🎉 | ✓ | ✓ | |
rocket | 🚀 | ✓ | ||
eyes | 👀 | ✓ | ||
fire | 🔥 | ✓ | ||
clap | 👏 | ✓ | ||
thinking | 🤔 | ✓ | ||
party | 🥳 | ✓ | ||
star | ⭐ | ✓ | ||
beer | 🍺 | ✓ | ||
sparkles | ✨ | ✓ | ||
hundred | 💯 | ✓ | ||
pray | 🙏 | ✓ | ||
muscle | 💪 | ✓ | ||
cool | 😎 | ✓ | ||
heart_eyes | 😍 | ✓ | ||
confused | 😕 | ✓ | ||
raised_hands | 🙌 | ✓ |
Sets in short:
updown(2):like,dislike. Exclusive.github(8):like,dislike,love,funny,wow,sad,angry,hooray.full(24): every row in the table above.
Example value for a setting or parameter:
like,love,fire,star,clap,rocket,heart_eyesCustom types are added via CLI or admin API and attached to a set. They are not listed in this table.
Button chunk placeholders (tpl)
| Placeholder | Description |
|---|---|
[[+emoji]] | Reaction type emoji |
[[+name]] | Type name (like, love, funny…) |
[[+count]] | Current count |
[[+active]] | 1 if the user chose this reaction, otherwise 0 |
Outer chunk placeholders (tplOuter)
| Placeholder | Description |
|---|---|
[[+output]] | HTML of all buttons |
[[+total]] | Sum of all reactions |
[[+api_url]] | API URL. The default outer writes it to data-api. JS can also resolve the API from the reactions.js path or Reactions.config.api |
[[+csrf]] | CSRF token for AJAX |
[[+class_key]] | Object class (as in the API, in the DB: object_class) |
[[+object_id]] | Object ID |
[[+set]] | Set key |
[[+context]] | Context |
[[+types]] | Comma-separated names of shown types (data-types for JS) |
[[+exclusive]] | 1 / 0: exclusive set (data-exclusive) |
[[+allow_multiple]] | 1 / 0: reactions_allow_multiple setting (data-allow-multiple) |
[[+layout]] | picker or bar after resolving auto (data-layout) |
[[+trigger]] | HTML for the + button in picker mode (empty in bar) |
The JS container needs the reactions-widget class and object data attributes (data-class-key, data-object-id). data-api is optional. See js.
Examples
Examples in MODX and Fenom syntax.
Set from reactions_default_set (no &set)
[[!Reactions]]{'!Reactions' | snippet}Exclusive: updown
[[!Reactions?
&set=`updown`
&class=`modResource`
&object=`[[*id]]`
&context=`web`
]]{'!Reactions' | snippet : [
'set' => 'updown',
'class' => 'modResource',
'object' => $_modx->resource.id,
'context' => 'web',
]}github — compact picker (default with layout=auto)
Chips for current reactions and a + button with a type grid. No long strip of 8 buttons.
[[!Reactions? &set=`github`]]
[[!Reactions? &set=`github` &layout=`picker`]]
[[!Reactions? &set=`github` &layout=`bar`]]{'!Reactions' | snippet : ['set' => 'github']}
{'!Reactions' | snippet : ['set' => 'github', 'layout' => 'picker']}
{'!Reactions' | snippet : ['set' => 'github', 'layout' => 'bar']}Up to 24 types: full (also picker by default)
[[!Reactions? &set=`full`]]
[[!Reactions? &set=`full` &layout=`bar`]]{'!Reactions' | snippet : ['set' => 'full']}
{'!Reactions' | snippet : ['set' => 'full', 'layout' => 'bar']}Without &types= for full, the system setting reactions_full_types is used. An empty setting means all 24 types in the popover.
Subset via &types= on full
[[!Reactions?
&set=`full`
&types=`like,love,fire,star,clap`
]]{'!Reactions' | snippet : [
'set' => 'full',
'types' => 'like,love,fire,star,clap',
]}Filter priority: &types= → otherwise reactions_full_types (full only) → the full set. Only names that are actually shown go into data-types.
Dropping unknown names in &types=
not_a_type is discarded. Types from the set remain.
[[!Reactions?
&set=`full`
&types=`like,angry,not_a_type`
]]{'!Reactions' | snippet : [
'set' => 'full',
'types' => 'like,angry,not_a_type',
]}Result: two buttons: like, angry.
&types= on github: names outside the set are ignored
fire exists in full but not in github → only like and love appear on screen.
[[!Reactions?
&set=`github`
&types=`like,love,fire`
]]{'!Reactions' | snippet : [
'set' => 'github',
'types' => 'like,love,fire',
]}miniShop3 product
Short class msProduct and product ID. The server resolves the FQCN itself.
[[!Reactions?
&set=`github`
&class=`msProduct`
&object=`[[*id]]`
&context=`web`
]]{'!Reactions' | snippet : [
'set' => 'github',
'class' => 'msProduct',
'object' => $_modx->resource.id,
'context' => 'web',
]}Same with exclusive:
[[!Reactions?
&set=`updown`
&class=`msProduct`
&object=`[[+id]]`
]]{'!Reactions' | snippet : [
'set' => 'updown',
'class' => 'msProduct',
'object' => $id,
]}Tickets comment
On MODX 3 the Tickets package is not verified yet. Call pattern:
[[!Reactions?
&class=`TicketComment`
&object=`[[+id]]`
&set=`updown`
]]{'!Reactions' | snippet : [
'class' => 'TicketComment',
'object' => $id,
'set' => 'updown',
]}Output to a placeholder
[[!Reactions?
&set=`updown`
&object=`[[*id]]`
&toPlaceholder=`pageReactions`
]]
[[+pageReactions]]{'!Reactions' | snippet : [
'set' => 'updown',
'object' => $_modx->resource.id,
'toPlaceholder' => 'pageReactions',
]}
{$_modx->getPlaceholder('pageReactions')}Custom button and outer chunks
[[!Reactions?
&set=`github`
&tpl=`myReactionBtn`
&tplOuter=`myReactionsWrap`
]]{'!Reactions' | snippet : [
'set' => 'github',
'tpl' => 'myReactionBtn',
'tplOuter' => 'myReactionsWrap',
]}In tplOuter keep the reactions-widget class and data attributes (data-class-key, data-object-id, data-exclusive, data-allow-multiple, data-layout…) plus the [[+trigger]] placeholder for picker mode. See js.
Button behavior
- A second click removes the reaction.
- In the
updownset (and anyexclusiveset) choosing another reaction replaces the previous one. - Several types at once: the set is not
exclusiveandreactions_allow_multiple=Yes(otherwise the server keeps one type per visitor even forgithub/full). - Counters update via AJAX without a page reload.
Loading scripts
Without reactions.js the buttons render but do not respond to clicks.
<link rel="stylesheet" href="[[++assets_url]]components/reactions/js/web/reactions.css">
<script src="[[++assets_url]]components/reactions/js/web/reactions.js" defer></script><link rel="stylesheet" href="{'assets_url' | config}components/reactions/js/web/reactions.css">
<script src="{'assets_url' | config}components/reactions/js/web/reactions.js" defer></script>