CBStats: purpose, syntax and outputs
CBStats displays dynamic statistics from ContentBuilder NG views directly inside Joomla articles while preserving view access rights and configuration. Simple example: {CBStats id=ViewID output=total}. See the description below for all syntax options.
CBStats: purpose, syntax and outputs
CBStats displays dynamic statistics from ContentBuilder NG views directly inside Joomla articles while preserving view access rights and configuration.
Simple example: {CBStats id=ViewID output=total}. See the sections below for all syntax options.
Syntax: {CBStats id=ViewID ...}. The default output is total.
Available outputs:
total: matching record count.form_name: view title or name.table: HTML value/count table.sum,min,max: numeric aggregates; ISO dates support chronological min/max.avg: arithmetic mean of numeric values (empty/non-numeric values are ignored).json: raw[{label,value}]array.pie: responsive Pie chart with dynamic colours, localized percentages, tooltip, detailed legend and total.bar: responsive horizontal Bar chart with values, percentages, tooltip, legend, total and sorting.histogram: numeric distribution grouped into explicitranges, for exampleranges='18-29;30-39;40-49;50+'.line: ordered trend chart, commonly with date or sequential categories, for exampleoutput=line limit=12.radar: multi-axis comparison chart; use 3–8 categories, for examplefield=Distance output=radar ranges='0-100;101-200;201+'.
Table, JSON, Pie, Bar, Histogram, Line and Radar use the same normalized PHP engine; avg uses the same normalized numeric values.
Simple examples:{CBStats id=25 output=total}{CBStats id=25 field=Route output=table}{CBStats id=25 field=Route output=json}{CBStats id=25 field=Route output=pie}{CBStats id=25 field=Route output=bar sort=value dir=desc}{CBStats id=25 field=Distance output=avg}{CBStats id=25 field=Distance output=histogram ranges='0-50;51-100;101+'}{CBStats id=25 field=Date output=line limit=12}{CBStats id=25 field=Score output=radar}
Merging views with idsum: idsum=25+27 replaces id= and accepts two to five unique view identifiers separated by +. Each view applies permissions and filters before values with the same exact label are added. Then add=, zero normalization, titles=, sorting and output are applied once to the merged result. output=form_name is not available with idsum. Examples: {CBStats idsum=25+27 field="Route" output="table" title="Monticyclo / Montigravel"} and {CBStats idsum=31+32+33+34+35 field="Distance" output="bar" title="BRM"}.
Distinct values
output=distinct counts the distinct non-empty values of field= after all normal CBStats filters, view/source restrictions and permissions have been applied.
It supports filter[field], filter[value], the same-field value= shorthand, * wildcards and | alternatives. Examples: {CBStats id=25 field=Department output=distinct} and {CBStats id=25 field=Department value="78|60" output=distinct}.
Remaining before a target
output=remaining target=200 subtracts the normal filtered CBStats total from the positive target and never returns less than zero.
All normal view, source, permission and record filters are applied first. Example: {CBStats id=15 output=remaining target=200}.
Editorial Card for free content
An editorial Card groups free HTML, CBStats and CBList tags without requiring the full Card markup. Use the complete recommended syntax: <div class="cb-card-editorial" data-card="v1" data-w="33">…</div>.
A direct <h1> to <h6 data-cb-card-title> becomes the coloured Card header and remains visible in the visual editor. An Hx heading without this attribute stays in the body. The legacy data-title syntax remains supported with its shared |h1 to |h6 and positive |remX suffixes. Without either title form, no header is rendered. data-card accepts h1–h6 and v1–v6; its default is v1. data-w accepts 33, 66 or 100; its default is 33. Invalid Card or width values use these safe defaults.
Example:<div class="cb-card-editorial" data-card="v1" data-w="33">
<h4 data-cb-card-title>Information</h4>
<p>Total: {CBStats id=15 output=total}</p>
<p>Distinct groups: {CBStats id=15 field=Group output=distinct}</p>
{CBList id=15 fields="Nom|Prenom" limit=5}
</div>
The standard HTML markup is preserved by TinyMCE and JCE. The renderer reuses the existing shared Card CSS and removes empty whitespace or non-breaking-space text nodes inserted between Cards in a cb-cards grid.
Filters, sorting and external values
Filtering on another field: field=Element-1 is the field grouped and displayed in the chart. filter[field]=Element-2 is the field used to filter records. filter[value]="Dét* | 3 | 4" keeps values beginning with Dét, or the exact value 3, or the exact value 4. The | character separates alternatives, surrounding spaces are ignored and, without *, matching is exact.
{CBStats id=15 field=Element-1 filter[field]=Element-2 filter[value]="Dét* | 3 | 4" output=bar}
Shortcut for the same field: when the filter applies to the displayed field, {CBStats id=15 field=Element-2 value="Dét* | 3 | 4" output=bar} is equivalent to {CBStats id=15 field=Element-2 filter[field]=Element-2 filter[value]="Dét* | 3 | 4" output=bar}. When the fields differ, use filter[field] and filter[value]. Do not confuse value= with values=, which is reserved for source=manual.
Examples:{CBStats id=25 field=Route output=pie add='100 km=-3'}{CBStats id=25 field=Route output=table titles='1=Group 1;2=Group 2'}{CBStats id=25 field=Route output=bar add='1=-2;2=3' titles='1=Group 1;2=Group 2' sort=value dir=desc}{CBStats id=15 field=Element-1 filter[field]=Element-2 filter[value]="Dét* | 3 | 4" output=bar}{CBStats id=15 field=Element-2 value="Dét* | 3 | 4" output=bar}
Total label and background
title='👥 Total registrations' customizes the global total label for Table, Pie and Bar.
titles='Original=Display title' customizes individual category labels.
headers='Route=Distance;Total=Participants' customizes only the two column headers of output=table. Unmapped headers remain unchanged; unknown keys and empty labels are ignored. Pie and Bar legends remain unchanged.
title=, titles= and headers= are independent.
CBStats adds the separator for the active language when it is omitted and does not duplicate an existing colon.
background= accepts transparent, hexadecimal colours, rgb(), rgba() and the documented safe named colours.
{CBStats id=25 field=Route output=table headers='Route=Distance;Total=Participants'}
Table column headers
headers='Route=Distance;Total=Participants' customizes only the two column headers of output=table. Unmapped headers remain unchanged; unknown keys and empty labels are ignored. Pie and Bar legends remain unchanged. title=, titles= and headers= are independent. export=manual preserves the mapping.
Result limit and total display
limit=10 keeps the first 10 statistical values after sort= and dir=. Without limit, all values are rendered. Numeric options must be strictly positive integers written without quotation marks.
After limiting, the displayed total and chart percentages are recalculated from the retained values only. No Other category is added.
{CBStats id=15 field=Town output=table sort=value dir=desc limit=10}{CBStats idsum=15+16 field=Club output=bar sort=value dir=desc limit=15}
Optional shared ContentBuilder NG Card
Use card=h1 to card=h6 or card=v1 to card=v6. For every variant, the title is horizontal and above the content. A header is displayed only with an explicit non-empty title=.
Card titles use h4 by default. Add |h1 to |h6 after the title to select a heading level, or |remX / |remX.X to set a positive visual size while keeping the semantic h4 level. Spaces around the last | are optional and suffixes are case-insensitive. An unrecognised suffix remains part of the complete title, which uses the default h4 rendering.
{CBStats id=15 field=Group output=pie title="Distribution | h4" card=h1}{CBStats id=15 field=Group output=pie title="Distribution | rem1.25" card=h1}
Override colours in Joomla user.css using the --cb-card-* custom properties.
Placing V Cards side by side
Put all three tags in one <div class="cb-cards">, with no <br> and without closing the container between tags. On desktop V Cards use three columns; on small screens one. An H Card spans the full row.
Example:<div class="cb-cards">
{CBStats id=15 field=Group output=pie title="Groups" card=v1}
{CBStats id=15 field=FirstName output=bar title="First names" card=v2}
{CBStats id=15 field=Group output=table title="Details" card=v3}
</div>
Card widths
Inside cb-cards, w=33 spans one column, w=66 two columns and w=100 the complete row. Write the value without quotation marks and use it only with card=. Without w=, V uses 33 and H uses 100. All Cards become full-width on small screens. A Card moves to the next row when insufficient space remains.
w= controls the Card; width= controls the chart inside it.
Example:<div class="cb-cards">
{CBStats id=15 field=Group output=pie title="Groups" card=v1 w=33}
{CBStats id=15 field=FirstName output=bar title="First names" card=v2 w=66 width=100%}
</div>
Complete two-row article example
Put up to six V Cards in one cb-cards container. The first three form the first row and the next cards the second. Do not insert <br> or close the container between rows. A standalone H Card can follow the container directly.
Joomla HTML example, without Markdown ``` markers:
<div class="cb-cards">
{CBStats id=15 field=Group output=pie title="Groups" card=v1}
{CBStats id=15 field=FirstName output=bar title="First names" card=v2}
{CBStats id=15 field=Group output=table title="Details" card=v3}
{CBStats id=15 field=Town output=pie title="Towns" card=v4}
{CBStats id=15 field=Age output=histogram ranges="18-29;30-39;40-49;50+" title="Ages" card=v5}
{CBStats id=15 output=total title="Total" card=v1}
</div>
{CBList id=15 fields="Nom|Prenom|Email" title="Latest records" sort=ID dir=desc limit=10 card=h1}
Customising Cards
For the whole site: add .cb-card-h1 { --cb-card-accent: #005a9c; --cb-card-header-color: #fff; } to the Joomla template’s user.css. Replace h1 with the required H/V variant.
For one article only: wrap the tags in <div class="my-cards">…</div>, then add <style>.my-cards .cb-card-h1 { --cb-card-accent: #005a9c; }</style> in the article when its editor and site policy allow style elements.
Advanced overrides: --cb-card-header-bg, --cb-card-header-color, --cb-card-bg, --cb-card-color and --cb-card-border-color.
Responsive chart dimensions
width= controls the chart container width and height= its height. Accepted values are a positive integer, px or %. A bare number becomes pixels: width=350 equals width=350px. CSS expressions, other units and values above 100% or 5000px are rejected.
Without options: Pie uses 80% of its container, is centred and is capped at 350px. Bar, Histogram, Line and Radar use 100% of the available width. No chart should create horizontal scrolling by default.
Explicit width: width=100% lets Pie fill the Card and removes its 350px maximum. width=300 fixes 300px. Prefer percentages inside small containers.
Explicit height: this disables the chart’s maintained aspect ratio. height=280 means 280px. height=80% is useful only when the parent already has a defined CSS height; otherwise use pixels.
Examples:{CBStats id=15 field=Group output=pie}{CBStats id=15 field=Group output=pie width=100%}{CBStats id=15 field=Group output=bar width=100% height=280}{CBStats id=15 field=Group output=radar width=80% height=320px}
Hide chart result elements
hide= accepts only total, values and graph, combined with | in any order. total hides only the displayed total, values hides the textual labels and values list below the graph without changing the graph itself, and graph hides the drawing while retaining that lightweight textual list. Without hide=, everything is displayed. Hiding all three elements produces a message instead of an empty block. The former total=hide syntax is rejected; use hide="total".
hide="total|values": complete graph only. hide="graph|total": textual list only. hide="graph": textual list and total. hide="values": complete graph and total. hide="graph|values": total only.
{CBStats id=15 field=GroupeVcmb output=bar hide="values"}{CBStats id=25 field=age output=histogram ranges="18-29;30-39;40-49;50-59;60+" hide="total|values"}{CBStats id=25 field=age output=radar ranges="18-29;30-39;40-49;50-59;60+" hide="graph|total"}
Manual mode — preserve statistics
source=manual uses only values=, without a ContentBuilder view, field or query. It preserves results when a view is reused.
{CBStats source=manual output=pie values='100 km=45;150 km=47;200 km=38;200 km (Formula)=30' title='👥 Total registrations'}
Outputs: pie, bar, table, total. add=, titles=, title=, sort=none|title|label|value and dir=asc|desc remain available. Duplicate labels are added. In labels, use \;, \= and \. Do not add id= or field=.
Manual export
Only export=manual displays the final results and visible source=manual syntax below Pie, Bar and Table outputs. Final labels after titles=, additions and sorting are written directly into values=; titles= is not copied.
{CBStats id=25 field=Route output=pie title='👥 Total registrations' export=manual}
The centered Copy syntax button copies exactly the syntax shown above it. On an already manual source, the normalized final syntax is displayed once without nesting.
URL/API, API + Rights and DEBUG
URL/API: all data outputs are testable through action=cbstats: json, table, pie, bar, histogram, line, radar, total, sum, min, max, avg and form_name. List and chart names return normalized data without HTML. ranges, add, titles, sort, dir and limit use the article-tag validation path.
API + Rights: check ACLs, fields published and enabled for API/Stats, the STATS permission and the view's API tab. No request bypasses view or field permissions.
DEBUG: safe diagnostics follow the view DEBUG setting. DEBUG grants no additional right and never bypasses ACLs.
Complete reference and processing order
Source: source, id, idsum, values. Data: field, filter[field], filter[value], value. Calculation: add, titles, ranges, sort, dir, limit. Output: output, headers, title, background, hide, card, width, height, export. Diagnostics: debug. The former total=hide is rejected; use hide="total".
Normal order: ACL → filters → grouping → add → zero normalisation → titles → ranges when required → sorting → limit → output and presentation.
Complete example:{CBStats id=15 field=Group filter[field]=Status filter[value]="Published*" add="External=2" titles="External=Guests" sort=value dir=desc limit=10 output=bar title="Distribution" hide="values" card=h1 width=100% height=320 export=manual}