You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2017/11/22 15:18:45 UTC

[myfaces-tobago] branch master updated: TOBAGO-1826: Possibility to access the "markup"s via JavaScript

This is an automated email from the ASF dual-hosted git repository.

lofwyr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git


The following commit(s) were added to refs/heads/master by this push:
     new 059438e  TOBAGO-1826: Possibility to access the "markup"s via JavaScript
059438e is described below

commit 059438ed4be01dd16efa21daf03d8889bec327f5
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Wed Nov 22 16:17:13 2017 +0100

    TOBAGO-1826: Possibility to access the "markup"s via JavaScript
---
 .../org/apache/myfaces/tobago/context/Markup.java  |  7 +++++
 .../internal/renderkit/renderer/BarRenderer.java   |  2 ++
 .../internal/renderkit/renderer/BoxRenderer.java   |  7 ++++-
 .../renderkit/renderer/ButtonsRenderer.java        |  7 ++++-
 .../renderkit/renderer/CommandRendererBase.java    |  1 +
 .../internal/renderkit/renderer/DateRenderer.java  |  1 +
 .../internal/renderkit/renderer/FileRenderer.java  |  1 +
 .../renderkit/renderer/FlexLayoutRenderer.java     |  3 +++
 .../renderkit/renderer/FlowLayoutRenderer.java     | 17 +++++++-----
 .../renderkit/renderer/FooterRenderer.java         |  7 ++++-
 .../internal/renderkit/renderer/FormRenderer.java  |  3 +++
 .../renderkit/renderer/GridLayoutRenderer.java     |  3 +++
 .../renderkit/renderer/HeaderRenderer.java         |  7 ++++-
 .../internal/renderkit/renderer/ImageRenderer.java |  8 +++++-
 .../internal/renderkit/renderer/InRenderer.java    | 10 ++++---
 .../renderer/LabelLayoutRendererBase.java          |  5 ++++
 .../internal/renderkit/renderer/LabelRenderer.java |  3 +++
 .../renderer/LinkInsideLinksRenderer.java          |  3 +++
 .../internal/renderkit/renderer/LinksRenderer.java |  3 +++
 .../renderkit/renderer/MessagesRenderer.java       |  6 ++++-
 .../renderkit/renderer/ObjectRenderer.java         |  7 ++++-
 .../internal/renderkit/renderer/OutRenderer.java   |  7 ++++-
 .../internal/renderkit/renderer/PageRenderer.java  |  1 +
 .../internal/renderkit/renderer/PanelRenderer.java |  5 +++-
 .../internal/renderkit/renderer/PopupRenderer.java | 14 +++++-----
 .../renderkit/renderer/ProgressRenderer.java       |  7 +++--
 .../renderkit/renderer/SectionRenderer.java        |  8 ++++--
 .../renderkit/renderer/SegmentLayoutRenderer.java  | 12 ++++++---
 .../renderer/SelectBooleanCheckboxRenderer.java    |  6 ++++-
 .../renderer/SelectManyCheckboxRenderer.java       |  6 ++++-
 .../renderer/SelectManyShuttleRenderer.java        | 10 +++++--
 .../renderer/SelectOneChoiceRenderer.java          |  6 ++++-
 .../renderkit/renderer/SelectOneRadioRenderer.java |  6 ++++-
 .../renderer/SeparatorInsideCommandRenderer.java   |  3 +++
 .../renderkit/renderer/SeparatorRenderer.java      |  6 +++++
 .../internal/renderkit/renderer/SheetRenderer.java |  4 ++-
 .../renderkit/renderer/SplitLayoutRenderer.java    |  3 +++
 .../renderkit/renderer/TabGroupRenderer.java       |  5 +++-
 .../renderkit/renderer/TreeIconRenderer.java       | 18 +++++++------
 .../renderkit/renderer/TreeIndentRenderer.java     | 14 +++++-----
 .../renderkit/renderer/TreeListboxRenderer.java    |  9 +++++--
 .../renderkit/renderer/TreeNodeRenderer.java       | 23 +++++++++-------
 .../internal/renderkit/renderer/TreeRenderer.java  | 12 +++++----
 .../renderkit/renderer/TreeSelectRenderer.java     | 31 +++++++++++++---------
 .../myfaces/tobago/internal/util/JsonUtils.java    | 20 ++++++++++++++
 .../tobago/renderkit/html/DataAttributes.java      |  5 ++++
 .../myfaces/tobago/context/MarkupUnitTest.java     | 12 ++++++++-
 .../tobago/internal/util/JsonUtilsUnitTest.java    | 16 +++++++++++
 48 files changed, 296 insertions(+), 84 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Markup.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Markup.java
index 9e3d1b9..946a259 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Markup.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Markup.java
@@ -377,6 +377,13 @@ public final class Markup implements Serializable, Iterable<String> {
     }
   }
 
+  /**
+   * Check if there is no value set inside this markup.
+   */
+  public boolean isEmpty() {
+    return !(value != null || values != null && values.length != 0);
+  }
+
   @Override
   public String toString() {
     if (value != null) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BarRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BarRenderer.java
index c51e770..e5ebbe6 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BarRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BarRenderer.java
@@ -27,6 +27,7 @@ import org.apache.myfaces.tobago.internal.component.AbstractUIForm;
 import org.apache.myfaces.tobago.internal.component.AbstractUILinks;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JQueryUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
@@ -58,6 +59,7 @@ public class BarRenderer extends RendererBase {
 
     writer.startElement(HtmlElements.NAV);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.BAR,
         TobagoClass.BAR.createMarkup(bar.getMarkup()),
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BoxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BoxRenderer.java
index 9a2be86..b1321a4 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BoxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/BoxRenderer.java
@@ -19,11 +19,14 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.Facets;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIBox;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.model.CollapseMode;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -40,6 +43,7 @@ public class BoxRenderer extends PanelRendererBase {
 
     final AbstractUIBox box = (AbstractUIBox) component;
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final Markup markup = box.getMarkup();
 
     final UIComponent label = ComponentUtils.getFacet(box, Facets.label);
     final String labelString = box.getLabel();
@@ -50,13 +54,14 @@ public class BoxRenderer extends PanelRendererBase {
 
     writer.writeClassAttribute(
         TobagoClass.BOX,
-        TobagoClass.BOX.createMarkup(box.getMarkup()),
+        TobagoClass.BOX.createMarkup(markup),
         TobagoClass.BOX.createDefaultMarkups(box),
         BootstrapClass.CARD,
         collapsed ? TobagoClass.COLLAPSED : null,
         box.getCustomClass());
     final String clientId = box.getClientId(facesContext);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, box);
     if (title != null) {
       writer.writeAttribute(HtmlAttributes.TITLE, title, true);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java
index 8a0f9ed..e04011f 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java
@@ -20,12 +20,15 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIButton;
 import org.apache.myfaces.tobago.internal.component.AbstractUIButtons;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlRoleValues;
@@ -41,14 +44,16 @@ public class ButtonsRenderer extends RendererBase {
   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
 
     final AbstractUIButtons buttons = (AbstractUIButtons) component;
+    final Markup markup = buttons.getMarkup();
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(buttons.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
 
     writer.writeClassAttribute(
         TobagoClass.BUTTONS,
-        TobagoClass.BUTTONS.createMarkup(buttons.getMarkup()),
+        TobagoClass.BUTTONS.createMarkup(markup),
         TobagoClass.BUTTONS.createDefaultMarkups(buttons),
         BootstrapClass.BTN_GROUP,
         buttons.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
index 8329a4c..8c48502 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
@@ -223,6 +223,7 @@ public abstract class CommandRendererBase extends DecodingCommandRendererBase {
     if (parentOfCommands) {
       writer.startElement(HtmlElements.SPAN);
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(command.getMarkup()), false);
 
       writer.writeClassAttribute(
           childOfButtonGroup ? null : dropdownSubmenu ? TobagoClass.DROPDOWN__SUBMENU : BootstrapClass.DROPDOWN,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java
index fd2f9ff..164725e 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java
@@ -69,6 +69,7 @@ public class DateRenderer extends InRenderer {
     writer.startElement(HtmlElements.DIV);
     if (date.isLabelLayoutSkip()) {
       writer.writeIdAttribute(date.getClientId());
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(date.getMarkup()), false);
     }
     writer.writeClassAttribute(TobagoClass.INPUT__GROUP__OUTER);
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
index ec2193b..9d15199 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
@@ -122,6 +122,7 @@ public class FileRenderer extends MessageLayoutRendererBase implements Component
     writer.startElement(HtmlElements.DIV);
     if (file.isLabelLayoutSkip()) {
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(file.getMarkup()), false);
     }
     writer.writeClassAttribute(
         TobagoClass.FILE,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlexLayoutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlexLayoutRenderer.java
index 3e4ffa0..962110d 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlexLayoutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlexLayoutRenderer.java
@@ -20,9 +20,11 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIFlexLayout;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -39,6 +41,7 @@ public class FlexLayoutRenderer extends RendererBase {
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(flexLayout.getClientId());
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(flexLayout.getMarkup()), false);
     writer.writeClassAttribute(
         TobagoClass.FLEX_LAYOUT,
         BootstrapClass.D_FLEX,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlowLayoutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlowLayoutRenderer.java
index 41aa1e3..04682f9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlowLayoutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FlowLayoutRenderer.java
@@ -20,10 +20,13 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIFlowLayout;
+import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.layout.TextAlign;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -37,16 +40,18 @@ public class FlowLayoutRenderer extends RendererBase {
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
-    final UIFlowLayout layout = (UIFlowLayout) component;
+    final UIFlowLayout flowLayout = (UIFlowLayout) component;
+    final Markup markup = flowLayout.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
-    writer.writeIdAttribute(layout.getClientId());
-    final TextAlign textAlign = layout.getTextAlign();
+    writer.writeIdAttribute(flowLayout.getClientId());
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
+    final TextAlign textAlign = flowLayout.getTextAlign();
     writer.writeClassAttribute(
         TobagoClass.FLOW_LAYOUT,
-        TobagoClass.FLOW_LAYOUT.createMarkup(layout.getMarkup()),
-        TobagoClass.FLOW_LAYOUT.createDefaultMarkups(layout),
-        layout.getCustomClass(),
+        TobagoClass.FLOW_LAYOUT.createMarkup(markup),
+        TobagoClass.FLOW_LAYOUT.createDefaultMarkups(flowLayout),
+        flowLayout.getCustomClass(),
         textAlign != null ? BootstrapClass.textAlign(textAlign) : null);
   }
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FooterRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FooterRenderer.java
index b3125f5..a248314 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FooterRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FooterRenderer.java
@@ -20,10 +20,13 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIFooter;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
@@ -38,12 +41,14 @@ public class FooterRenderer extends RendererBase {
   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final UIFooter footer = (UIFooter) component;
+    final Markup markup = footer.getMarkup();
     writer.startElement(HtmlElements.FOOTER);
     writer.writeIdAttribute(component.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
 
     writer.writeClassAttribute(
         TobagoClass.FOOTER,
-        TobagoClass.FOOTER.createMarkup(footer.getMarkup()),
+        TobagoClass.FOOTER.createMarkup(markup),
         TobagoClass.FOOTER.createDefaultMarkups(footer),
         footer.isFixed() ? BootstrapClass.FIXED_BOTTOM : null,
         footer.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java
index 7221936..5d42415 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java
@@ -20,9 +20,11 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.internal.component.AbstractUIForm;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -41,6 +43,7 @@ public class FormRenderer extends RendererBase {
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(form.getMarkup()), false);
     writer.writeClassAttribute(
         TobagoClass.FORM,
         inline ? BootstrapClass.D_INLINE : null,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/GridLayoutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/GridLayoutRenderer.java
index 1888159..8f2786d 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/GridLayoutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/GridLayoutRenderer.java
@@ -22,9 +22,11 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.component.UIStyle;
 import org.apache.myfaces.tobago.internal.component.AbstractUIGridLayout;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.layout.MeasureList;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlRoleValues;
@@ -48,6 +50,7 @@ public class GridLayoutRenderer extends RendererBase {
     writer.startElement(HtmlElements.DIV);
     writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.PRESENTATION.toString(), false);
     writer.writeIdAttribute(gridLayout.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(gridLayout.getMarkup()), false);
     writer.writeClassAttribute(TobagoClass.GRID_LAYOUT);
 
     final MeasureList columns = MeasureList.parse(gridLayout.getColumns());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/HeaderRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/HeaderRenderer.java
index f6acbb4..faa9ced 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/HeaderRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/HeaderRenderer.java
@@ -20,10 +20,13 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIHeader;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
@@ -38,14 +41,16 @@ public class HeaderRenderer extends RendererBase {
   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final UIHeader header = (UIHeader) component;
+    final Markup markup = header.getMarkup();
     writer.startElement(HtmlElements.HEADER);
     writer.writeIdAttribute(component.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     // TBD: NAVBAR_DARK and BG_INVERSE should not be the default
     // TBD: how to configure it when it is needed, with customClass, or with markup?
 
     writer.writeClassAttribute(
         TobagoClass.HEADER,
-        TobagoClass.HEADER.createMarkup(header.getMarkup()),
+        TobagoClass.HEADER.createMarkup(markup),
         TobagoClass.HEADER.createDefaultMarkups(header),
         header.isFixed() ? BootstrapClass.FIXED_TOP : null,
         header.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ImageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ImageRenderer.java
index c7f3e54..5c93871 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ImageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ImageRenderer.java
@@ -19,14 +19,17 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUICommandBase;
 import org.apache.myfaces.tobago.internal.component.AbstractUIImage;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
@@ -49,9 +52,11 @@ public class ImageRenderer extends RendererBase {
         || (image.getParent() instanceof AbstractUICommandBase
         && ((AbstractUICommandBase) image.getParent()).isDisabled());
     final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, image);
+    final Markup markup = image.getMarkup();
     if (fontAwesome) {
       writer.startElement(HtmlElements.I);
       writer.writeIdAttribute(image.getClientId(facesContext));
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       writer.writeClassAttribute(
           Icons.FA,
           Icons.custom(value),
@@ -62,12 +67,13 @@ public class ImageRenderer extends RendererBase {
       final String alt = image.getAlt();
       writer.startElement(HtmlElements.IMG);
       writer.writeIdAttribute(image.getClientId(facesContext));
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       HtmlRendererUtils.writeDataAttributes(facesContext, writer, image);
       writer.writeAttribute(HtmlAttributes.SRC, value, true);
       writer.writeAttribute(HtmlAttributes.ALT, alt != null ? alt : "", true);
       writer.writeClassAttribute(
           TobagoClass.IMAGE,
-          TobagoClass.IMAGE.createMarkup(image.getMarkup()),
+          TobagoClass.IMAGE.createMarkup(markup),
           TobagoClass.IMAGE.createDefaultMarkups(image),
           disabled ? BootstrapClass.DISABLED : null,
           image.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
index 945fae7..7c67348 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
@@ -22,6 +22,7 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.component.Facets;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIButton;
 import org.apache.myfaces.tobago.internal.component.AbstractUIInput;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneChoice;
@@ -33,6 +34,7 @@ import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
@@ -71,6 +73,7 @@ public class InRenderer extends MessageLayoutRendererBase {
     final boolean readonly = input.isReadonly();
     final boolean disabled = input.isDisabled();
     final boolean required = ComponentUtils.getBooleanAttribute(input, Attributes.required);
+    final Markup markup = input.getMarkup();
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
@@ -81,6 +84,7 @@ public class InRenderer extends MessageLayoutRendererBase {
       writer.startElement(HtmlElements.DIV); // Wrapping the field to fix input groups with flexLeft/flexRight
       if (input.isLabelLayoutSkip()) {
         writer.writeIdAttribute(clientId);
+        writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       }
       writer.writeClassAttribute(TobagoClass.INPUT__GROUP__OUTER);
       writer.startElement(HtmlElements.DIV);
@@ -114,8 +118,8 @@ public class InRenderer extends MessageLayoutRendererBase {
         maxLength = lengthValidator.getMaximum();
         minLength = lengthValidator.getMinimum();
       } else if (validator instanceof RegexValidator) {
-          RegexValidator regexValidator = (RegexValidator) validator;
-          pattern = regexValidator.getPattern();
+        RegexValidator regexValidator = (RegexValidator) validator;
+        pattern = regexValidator.getPattern();
       }
     }
     if (maxLength > 0) {
@@ -138,7 +142,7 @@ public class InRenderer extends MessageLayoutRendererBase {
 
     writer.writeClassAttribute(
         getRendererCssClass(),
-        getRendererCssClass().createMarkup(input.getMarkup()),
+        getRendererCssClass().createMarkup(markup),
         getRendererCssClass().createDefaultMarkups(input),
         BootstrapClass.borderColor(ComponentUtils.getMaximumSeverity(input)),
         BootstrapClass.FORM_CONTROL,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
index 1128448..25beb01 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
@@ -23,12 +23,15 @@ import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.component.LabelLayout;
 import org.apache.myfaces.tobago.component.SupportsAccessKey;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIStyle;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -124,6 +127,7 @@ public abstract class LabelLayoutRendererBase extends DecodingInputRendererBase
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     String clientId = component.getClientId(facesContext);
+    final Markup markup = (Markup) ComponentUtils.getAttribute(component, Attributes.markup);
 
     // possible values:
     // - none
@@ -166,6 +170,7 @@ public abstract class LabelLayoutRendererBase extends DecodingInputRendererBase
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
 
     writer.writeClassAttribute(
         flex ? TobagoClass.FLEX_LAYOUT : null,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelRenderer.java
index c10904d..5ec22fa 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelRenderer.java
@@ -24,10 +24,12 @@ import org.apache.myfaces.tobago.component.UILabel;
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -79,6 +81,7 @@ public class LabelRenderer extends RendererBase implements ComponentSystemEventL
         BootstrapClass.COL_FORM_LABEL,
         label.getCustomClass());
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(label.getMarkup()), false);
     if (forId != null) {
       writer.writeAttribute(HtmlAttributes.FOR, forId, false);
     }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkInsideLinksRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkInsideLinksRenderer.java
index 7e1d62d..d963e16 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkInsideLinksRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkInsideLinksRenderer.java
@@ -20,8 +20,10 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -40,6 +42,7 @@ public class LinkInsideLinksRenderer extends LinkRenderer {
     writer.startElement(HtmlElements.LI);
     if (parentOfCommands) {
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(command.getMarkup()), false);
     }
 
     writer.writeClassAttribute(
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
index 26c6a79..695fa8e 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
@@ -22,10 +22,12 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.component.AbstractUILink;
 import org.apache.myfaces.tobago.internal.component.AbstractUILinks;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -42,6 +44,7 @@ public class LinksRenderer extends RendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     writer.startElement(HtmlElements.UL);
     writer.writeIdAttribute(links.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(links.getMarkup()), false);
     writer.writeClassAttribute(TobagoClass.LINKS, getExtraCssItem(), links.getCustomClass());
   }
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessagesRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessagesRenderer.java
index 7c7110b..ac5b3bd 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessagesRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessagesRenderer.java
@@ -20,7 +20,9 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIMessages;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
@@ -75,9 +77,11 @@ public class MessagesRenderer extends RendererBase {
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(messages.getClientId(facesContext));
+    final Markup markup = messages.getMarkup();
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.MESSAGES,
-        TobagoClass.MESSAGES.createMarkup(messages.getMarkup()),
+        TobagoClass.MESSAGES.createMarkup(markup),
         TobagoClass.MESSAGES.createDefaultMarkups(messages),
         messages.getCustomClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ObjectRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ObjectRenderer.java
index e76c17f..5df2bab 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ObjectRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ObjectRenderer.java
@@ -20,10 +20,13 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIObject;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.context.TobagoResourceBundle;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
@@ -37,11 +40,13 @@ public class ObjectRenderer extends RendererBase {
   public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
     final UIObject object = (UIObject) component;
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final Markup markup = object.getMarkup();
 
     writer.startElement(HtmlElements.IFRAME);
     writer.writeAttribute(HtmlAttributes.FRAMEBORDER, "0", false);
     final String clientId = object.getClientId(facesContext);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     String name = object.getName();
     if (name == null) {
       name = clientId;
@@ -51,7 +56,7 @@ public class ObjectRenderer extends RendererBase {
     writer.writeAttribute(HtmlAttributes.SRC, object.getSrc(), true);
     writer.writeClassAttribute(
         TobagoClass.OBJECT,
-        TobagoClass.OBJECT.createMarkup(object.getMarkup()),
+        TobagoClass.OBJECT.createMarkup(markup),
         TobagoClass.OBJECT.createDefaultMarkups(object),
         object.getCustomClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java
index 1ec331d..7bcfc2c 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java
@@ -21,11 +21,14 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UIOut;
 import org.apache.myfaces.tobago.config.TobagoConfig;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIOut;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.sanitizer.SanitizeMode;
@@ -53,17 +56,19 @@ public class OutRenderer extends MessageLayoutRendererBase {
 
     final boolean escape = out.isEscape();
     final boolean compact = out.isCompact() || !out.isCreateSpan();
+    final Markup markup = out.getMarkup();
 
     if (!compact) {
       writer.startElement(HtmlElements.SPAN);
       if (out.isLabelLayoutSkip()) {
         writer.writeIdAttribute(out.getClientId());
+        writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       }
       HtmlRendererUtils.writeDataAttributes(facesContext, writer, out);
 
       writer.writeClassAttribute(
           TobagoClass.OUT,
-          TobagoClass.OUT.createMarkup(out.getMarkup()),
+          TobagoClass.OUT.createMarkup(markup),
           TobagoClass.OUT.createDefaultMarkups(out),
           BootstrapClass.FORM_CONTROL_PLAINTEXT,
           out.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
index b8ee5d1..d63fdea 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
@@ -261,6 +261,7 @@ public class PageRenderer extends RendererBase {
         spread,
         page.getCustomClass());
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, page);
 
     writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, page)));
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java
index 3e74058..d48b653 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java
@@ -22,6 +22,7 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.component.Facets;
 import org.apache.myfaces.tobago.component.UIPanel;
 import org.apache.myfaces.tobago.component.UIReload;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
@@ -46,13 +47,15 @@ public class PanelRenderer extends PanelRendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final String clientId = panel.getClientId(facesContext);
     final boolean collapsed = panel.isCollapsed();
+    final Markup markup = panel.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
 
     writer.writeClassAttribute(
         TobagoClass.PANEL,
-        TobagoClass.PANEL.createMarkup(panel.getMarkup()),
+        TobagoClass.PANEL.createMarkup(markup),
         TobagoClass.PANEL.createDefaultMarkups(panel),
         collapsed ? TobagoClass.COLLAPSED : null,
         panel.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PopupRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PopupRenderer.java
index 31e5384..1e6287b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PopupRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PopupRenderer.java
@@ -22,9 +22,11 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIPopup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.model.CollapseMode;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlRoleValues;
@@ -44,21 +46,21 @@ public class PopupRenderer extends PanelRendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final String clientId = popup.getClientId(facesContext);
     final boolean collapsed = popup.isCollapsed();
-    Markup popupMarkup = popup.getMarkup() != null ? popup.getMarkup() : Markup.NULL;
+    final Markup markup = popup.getMarkup();
 
     // this makes the popup NOT closable with a click to the background
     ComponentUtils.putDataAttribute(popup, "backdrop", "static");
 
     writer.startElement(HtmlElements.DIV);
-
+    writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.POPUP,
-        TobagoClass.POPUP.createMarkup(popup.getMarkup()),
+        TobagoClass.POPUP.createMarkup(markup),
         TobagoClass.POPUP.createDefaultMarkups(popup),
         BootstrapClass.MODAL,
         BootstrapClass.FADE,
         popup.getCustomClass());
-    writer.writeIdAttribute(clientId);
     writer.writeAttribute(HtmlAttributes.TABINDEX, -1);
     writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.DIALOG.toString(), false);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, popup);
@@ -66,8 +68,8 @@ public class PopupRenderer extends PanelRendererBase {
     writer.startElement(HtmlElements.DIV);
     writer.writeClassAttribute(
         BootstrapClass.MODAL_DIALOG,
-        popupMarkup.contains(Markup.LARGE) ? BootstrapClass.MODAL_LG : null,
-        popupMarkup.contains(Markup.SMALL) ? BootstrapClass.MODAL_SM : null);
+        markup != null && markup.contains(Markup.LARGE) ? BootstrapClass.MODAL_LG : null,
+        markup != null && markup.contains(Markup.SMALL) ? BootstrapClass.MODAL_SM : null);
     writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.DOCUMENT.toString(), false);
     writer.startElement(HtmlElements.DIV);
     writer.writeClassAttribute(BootstrapClass.MODAL_CONTENT);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java
index c0f7a2c..2690602 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java
@@ -21,6 +21,7 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.component.UIStyle;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIProgress;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JsonUtils;
@@ -31,6 +32,7 @@ import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.Arias;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlRoleValues;
@@ -53,16 +55,17 @@ public class ProgressRenderer extends RendererBase {
     final double value = progress.getRangeValue();
     final double max = progress.getRangeMax();
     final double percent = value / max;
+    final Markup markup = progress.getMarkup();
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     writer.startElement(HtmlElements.DIV);
     final String clientId = progress.getClientId(facesContext);
     writer.writeIdAttribute(clientId);
-
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.PROGRESS,
-        TobagoClass.PROGRESS.createMarkup(progress.getMarkup()),
+        TobagoClass.PROGRESS.createMarkup(markup),
         TobagoClass.PROGRESS.createDefaultMarkups(progress),
         BootstrapClass.PROGRESS,
         progress.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SectionRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SectionRenderer.java
index fb4082b..b02da04 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SectionRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SectionRenderer.java
@@ -20,11 +20,14 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.Facets;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISection;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.model.CollapseMode;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
@@ -42,13 +45,14 @@ public class SectionRenderer extends PanelRendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final String clientId = section.getClientId(facesContext);
     final boolean collapsed = section.isCollapsed();
+    final Markup markup = section.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(clientId);
-
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.SECTION,
-        TobagoClass.SECTION.createMarkup(section.getMarkup()),
+        TobagoClass.SECTION.createMarkup(markup),
         TobagoClass.SECTION.createDefaultMarkups(section),
         collapsed ? TobagoClass.COLLAPSED : null,
         section.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SegmentLayoutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SegmentLayoutRenderer.java
index d9e011e..f08b82a 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SegmentLayoutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SegmentLayoutRenderer.java
@@ -22,11 +22,14 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.component.LabelLayout;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
 import org.apache.myfaces.tobago.component.UISegmentLayout;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISegmentLayout;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.layout.MarginTokens;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 import org.slf4j.Logger;
@@ -51,18 +54,21 @@ public class SegmentLayoutRenderer extends RendererBase {
 
   @Override
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
-    final AbstractUISegmentLayout layout = (AbstractUISegmentLayout) component;
+
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISegmentLayout layout = (AbstractUISegmentLayout) component;
+    final Markup markup = layout.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
+    writer.writeIdAttribute(layout.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
 //    writer.writeClassAttribute(BootstrapClass.FORM_HORIZONTAL, BootstrapClass.CONTAINER_FLUID);
     writer.writeClassAttribute(
         TobagoClass.SEGMENT_LAYOUT,
-        TobagoClass.SEGMENT_LAYOUT.createMarkup(layout.getMarkup()),
+        TobagoClass.SEGMENT_LAYOUT.createMarkup(markup),
         TobagoClass.SEGMENT_LAYOUT.createDefaultMarkups(layout),
         BootstrapClass.ROW);
 //    writer.writeClassAttribute(Classes.create(layout), BootstrapClass.FORM_GROUP);
-    writer.writeIdAttribute(layout.getClientId(facesContext));
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
index bb0303d..8d944e6 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectBooleanCheckbox;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
@@ -28,6 +29,7 @@ import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
@@ -79,15 +81,17 @@ public class SelectBooleanCheckboxRenderer extends MessageLayoutRendererBase {
     final boolean disabled = select.isDisabled();
     final LabelWithAccessKey label = new LabelWithAccessKey(select, true);
     final String itemLabel = select.getItemLabel();
+    final Markup markup = select.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
     if (select.isLabelLayoutSkip()) {
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     }
 
     writer.writeClassAttribute(
         TobagoClass.SELECT_BOOLEAN_CHECKBOX,
-        TobagoClass.SELECT_BOOLEAN_CHECKBOX.createMarkup(select.getMarkup()),
+        TobagoClass.SELECT_BOOLEAN_CHECKBOX.createMarkup(markup),
         TobagoClass.SELECT_BOOLEAN_CHECKBOX.createDefaultMarkups(select),
         getOuterCssItems(facesContext, select),
         disabled ? BootstrapClass.DISABLED : null,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
index a599986..a7c07e2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyCheckbox;
 import org.apache.myfaces.tobago.internal.util.ArrayUtils;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
@@ -28,6 +29,7 @@ import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
@@ -52,15 +54,17 @@ public class SelectManyCheckboxRenderer extends SelectManyRendererBase {
     final boolean readonly = select.isReadonly();
     final boolean required = select.isRequired();
     final boolean inline = select.isInline();
+    final Markup markup = select.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
     if (select.isLabelLayoutSkip()) {
       writer.writeIdAttribute(id);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     }
 
     writer.writeClassAttribute(
         TobagoClass.SELECT_MANY_CHECKBOX,
-        TobagoClass.SELECT_MANY_CHECKBOX.createMarkup(select.getMarkup()),
+        TobagoClass.SELECT_MANY_CHECKBOX.createMarkup(markup),
         TobagoClass.SELECT_MANY_CHECKBOX.createDefaultMarkups(select),
         inline ? TobagoClass.SELECT_MANY_CHECKBOX__INLINE : null,
         select.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java
index dd49077..88a9137 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java
@@ -20,6 +20,7 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UISelectManyShuttle;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
@@ -27,6 +28,7 @@ import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlButtonTypes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
@@ -43,16 +45,20 @@ public class SelectManyShuttleRenderer extends SelectManyRendererBase {
 
   @Override
   public void encodeBeginField(final FacesContext facesContext, final UIComponent component) throws IOException {
+
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final UISelectManyShuttle select = (UISelectManyShuttle) component;
     final String clientId = select.getClientId(facesContext);
-    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final Markup markup = select.getMarkup();
+
     writer.startElement(HtmlElements.DIV);
     if (select.isLabelLayoutSkip()) {
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     }
     writer.writeClassAttribute(
         TobagoClass.SELECT_MANY_SHUTTLE,
-        TobagoClass.SELECT_MANY_SHUTTLE.createMarkup(select.getMarkup()),
+        TobagoClass.SELECT_MANY_SHUTTLE.createMarkup(markup),
         TobagoClass.SELECT_MANY_SHUTTLE.createDefaultMarkups(select),
         select.getCustomClass());
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, select);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java
index 7d6ced4..429f8d9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java
@@ -20,12 +20,14 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UISelectOneChoice;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -53,9 +55,11 @@ public class SelectOneChoiceRenderer extends SelectOneRendererBase {
     final Iterable<SelectItem> items = SelectItemUtils.getItemIterator(facesContext, select);
     final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, select);
     final boolean disabled = !items.iterator().hasNext() || select.isDisabled() || select.isReadonly();
+    final Markup markup = select.getMarkup();
 
     writer.startElement(HtmlElements.SELECT);
     writer.writeIdAttribute(fieldId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeNameAttribute(clientId);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, select);
     writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
@@ -63,7 +67,7 @@ public class SelectOneChoiceRenderer extends SelectOneRendererBase {
 
     writer.writeClassAttribute(
         TobagoClass.SELECT_ONE_CHOICE,
-        TobagoClass.SELECT_ONE_CHOICE.createMarkup(select.getMarkup()),
+        TobagoClass.SELECT_ONE_CHOICE.createMarkup(markup),
         TobagoClass.SELECT_ONE_CHOICE.createDefaultMarkups(select), //readonly, disabled
         BootstrapClass.borderColor(ComponentUtils.getMaximumSeverity(select)),
         BootstrapClass.FORM_CONTROL,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
index eec6185..3b384dd 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneRadio;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JsonUtils;
@@ -28,6 +29,7 @@ import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
@@ -53,15 +55,17 @@ public class SelectOneRadioRenderer extends SelectOneRendererBase {
     final boolean readonly = select.isReadonly();
     final boolean required = select.isRequired();
     final boolean inline = select.isInline();
+    final Markup markup = select.getMarkup();
 
     writer.startElement(HtmlElements.DIV);
     if (select.isLabelLayoutSkip()) {
       writer.writeIdAttribute(id);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     }
 
     writer.writeClassAttribute(
         TobagoClass.SELECT_ONE_RADIO,
-        TobagoClass.SELECT_ONE_RADIO.createMarkup(select.getMarkup()),
+        TobagoClass.SELECT_ONE_RADIO.createMarkup(markup),
         TobagoClass.SELECT_ONE_RADIO.createDefaultMarkups(select),
         inline ? TobagoClass.SELECT_ONE_RADIO__INLINE : null,
         select.getCustomClass());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorInsideCommandRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorInsideCommandRenderer.java
index 1246556..c9e490b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorInsideCommandRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorInsideCommandRenderer.java
@@ -20,8 +20,10 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UISeparator;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -39,6 +41,7 @@ public class SeparatorInsideCommandRenderer extends SeparatorRenderer {
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(separator.getMarkup()), false);
     writer.writeClassAttribute(
         TobagoClass.SEPARATOR,
         BootstrapClass.DROPDOWN_DIVIDER,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorRenderer.java
index 88d9cf5..c3d7a6a 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SeparatorRenderer.java
@@ -22,8 +22,11 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.component.Facets;
 import org.apache.myfaces.tobago.component.UILabel;
 import org.apache.myfaces.tobago.component.UISeparator;
+import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
@@ -41,10 +44,12 @@ public class SeparatorRenderer extends RendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final String clientId = separator.getClientId(facesContext);
     final String label = getLabel(separator);
+    final Markup markup = separator.getMarkup();
 
     if (label != null) {
       writer.startElement(HtmlElements.P);
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       writer.writeClassAttribute(
           TobagoClass.SEPARATOR,
           TobagoClass.SEPARATOR.createMarkup(separator.getMarkup()),
@@ -55,6 +60,7 @@ public class SeparatorRenderer extends RendererBase {
     } else {
       writer.startElement(HtmlElements.HR);
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       writer.writeClassAttribute(
           TobagoClass.SEPARATOR,
           TobagoClass.SEPARATOR.createMarkup(separator.getMarkup()),
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
index 20b6299..238d2bf 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
@@ -143,6 +143,7 @@ public class SheetRenderer extends RendererBase {
 
     final UISheet sheet = (UISheet) component;
     final String sheetId = sheet.getClientId(facesContext);
+    final Markup markup = sheet.getMarkup();
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     UIComponent header = sheet.getHeader();
@@ -179,10 +180,11 @@ public class SheetRenderer extends RendererBase {
     // Outer sheet div
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(sheetId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, sheet);
     writer.writeClassAttribute(
         TobagoClass.SHEET,
-        TobagoClass.SHEET.createMarkup(sheet.getMarkup()),
+        TobagoClass.SHEET.createMarkup(markup),
         TobagoClass.SHEET.createDefaultMarkups(sheet),
         sheet.getCustomClass());
     final UIComponent facetReload = ComponentUtils.getFacet(sheet, Facets.reload);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SplitLayoutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SplitLayoutRenderer.java
index 572df7b..2b30bd0 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SplitLayoutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SplitLayoutRenderer.java
@@ -22,9 +22,11 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
 import org.apache.myfaces.tobago.apt.annotation.Preliminary;
 import org.apache.myfaces.tobago.internal.component.AbstractUISplitLayout;
 import org.apache.myfaces.tobago.internal.layout.LayoutUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 import org.slf4j.Logger;
@@ -66,6 +68,7 @@ public class SplitLayoutRenderer extends RendererBase {
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(splitLayout.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(splitLayout.getMarkup()), false);
     writer.writeClassAttribute(
         BootstrapClass.D_FLEX, // tbd: SPLIT_LAYOUT
         splitLayout.isHorizontal() ? BootstrapClass.FLEX_ROW : BootstrapClass.FLEX_COLUMN);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
index b643d5a..a5292c9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
@@ -143,13 +143,15 @@ public class TabGroupRenderer extends RendererBase implements ComponentSystemEve
     final String clientId = tabGroup.getClientId(facesContext);
     final String hiddenId = clientId + TabGroupRenderer.ACTIVE_INDEX_POSTFIX;
     final SwitchType switchType = tabGroup.getSwitchType();
+    final Markup markup = tabGroup.getMarkup();
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.TAB_GROUP,
-        TobagoClass.TAB_GROUP.createMarkup(tabGroup.getMarkup()),
+        TobagoClass.TAB_GROUP.createMarkup(markup),
         TobagoClass.TAB_GROUP.createDefaultMarkups(tabGroup),
         tabGroup.getCustomClass());
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, tabGroup);
@@ -235,6 +237,7 @@ public class TabGroupRenderer extends RendererBase implements ComponentSystemEve
 
           writer.startElement(HtmlElements.LI);
           writer.writeIdAttribute(tabId);
+          writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
           writer.writeClassAttribute(
               TobagoClass.TAB,
               TobagoClass.TAB.createMarkup(markup),
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIconRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIconRenderer.java
index 0a00920..5ee3453 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIconRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIconRenderer.java
@@ -23,6 +23,7 @@ import org.apache.myfaces.tobago.component.UITreeIcon;
 import org.apache.myfaces.tobago.component.UITreeNode;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
@@ -58,15 +59,15 @@ public class TreeIconRenderer extends RendererBase {
   @Override
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
-    final UITreeIcon image = (UITreeIcon) component;
-    final AbstractUIData data = ComponentUtils.findAncestor(image, AbstractUIData.class);
-    final UITreeNode node = ComponentUtils.findAncestor(image, UITreeNode.class);
+    final UITreeIcon treeIcon = (UITreeIcon) component;
+    final AbstractUIData data = ComponentUtils.findAncestor(treeIcon, AbstractUIData.class);
+    final UITreeNode node = ComponentUtils.findAncestor(treeIcon, UITreeNode.class);
     final boolean folder = node.isFolder();
     final boolean expanded = folder && data.getExpandedState().isExpanded(node.getPath());
 
-    final String value = (String) image.getValue();
-    String closed = image.getClosed();
-    String open = image.getOpen();
+    final String value = (String) treeIcon.getValue();
+    String closed = treeIcon.getClosed();
+    String open = treeIcon.getOpen();
 
     if (closed == null) {
       closed = value;
@@ -90,7 +91,8 @@ public class TreeIconRenderer extends RendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     writer.startElement(HtmlElements.SPAN);
-    writer.writeIdAttribute(image.getClientId());
+    writer.writeIdAttribute(treeIcon.getClientId());
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(treeIcon.getMarkup()), false);
     writer.writeClassAttribute(TobagoClass.TREE_NODE__TOGGLE);
 
     if (StringUtils.startsWith(source, "fa-")) {
@@ -103,7 +105,7 @@ public class TreeIconRenderer extends RendererBase {
       writer.endElement(HtmlElements.I);
     } else {
       writer.startElement(HtmlElements.IMG);
-      HtmlRendererUtils.writeDataAttributes(facesContext, writer, image);
+      HtmlRendererUtils.writeDataAttributes(facesContext, writer, treeIcon);
       writer.writeAttribute(HtmlAttributes.SRC, source, true);
       if (folder) {
         writer.writeAttribute(DataAttributes.OPEN, open, true);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIndentRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIndentRenderer.java
index 8f67d64..68ec1f1 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIndentRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeIndentRenderer.java
@@ -24,6 +24,7 @@ import org.apache.myfaces.tobago.component.UITreeIndent;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
@@ -43,16 +44,16 @@ public class TreeIndentRenderer extends RendererBase {
   @Override
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
-    final UITreeIndent indent = (UITreeIndent) component;
-    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(indent, AbstractUITreeNodeBase.class);
-    final AbstractUIData data = ComponentUtils.findAncestor(indent, AbstractUIData.class);
+    final UITreeIndent treeIndent = (UITreeIndent) component;
+    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(treeIndent, AbstractUITreeNodeBase.class);
+    final AbstractUIData data = ComponentUtils.findAncestor(treeIndent, AbstractUIData.class);
 
     final boolean folder = node.isFolder();
     final int level = node.getLevel();
     final List<Boolean> junctions = node.getJunctions();
 
     final boolean showRoot = data.isShowRoot();
-    final boolean showJunctions = indent.isShowJunctions();
+    final boolean showJunctions = treeIndent.isShowJunctions();
     final boolean showRootJunction = data.isShowRootJunction();
     final boolean expanded = folder && data.getExpandedState().isExpanded(node.getPath());
     final boolean showLines = showJunctions && data instanceof UITree; // sheet should not show lines
@@ -61,8 +62,9 @@ public class TreeIndentRenderer extends RendererBase {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     writer.startElement(HtmlElements.SPAN);
-    writer.writeIdAttribute(indent.getClientId(facesContext));
-    HtmlRendererUtils.writeDataAttributes(facesContext, writer, indent);
+    writer.writeIdAttribute(treeIndent.getClientId(facesContext));
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(treeIndent.getMarkup()), false);
+    HtmlRendererUtils.writeDataAttributes(facesContext, writer, treeIndent);
     writer.writeClassAttribute(TobagoClass.TREE_NODE__TOGGLE);
 
     // encode indent
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeListboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeListboxRenderer.java
index 19d41e5..5289361 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeListboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeListboxRenderer.java
@@ -23,9 +23,11 @@ import org.apache.myfaces.tobago.component.UITreeLabel;
 import org.apache.myfaces.tobago.component.UITreeListbox;
 import org.apache.myfaces.tobago.component.UITreeNode;
 import org.apache.myfaces.tobago.component.UITreeSelect;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUITree;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeListbox;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -51,9 +53,10 @@ public class TreeListboxRenderer extends RendererBase {
   @Override
   public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
 
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final UITreeListbox tree = (UITreeListbox) component;
     final String clientId = tree.getClientId(facesContext);
-    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final Markup markup = tree.getMarkup();
     //    final Style scrollDivStyle = new Style();
 
     writer.startElement(HtmlElements.DIV);
@@ -64,9 +67,11 @@ public class TreeListboxRenderer extends RendererBase {
 //    writer.writeStyleAttribute(scrollDivStyle);
 
     writer.startElement(HtmlElements.DIV);
+    // todo: the id must be in this DIV
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.TREE_LISTBOX,
-        TobagoClass.TREE_LISTBOX.createMarkup(tree.getMarkup()),
+        TobagoClass.TREE_LISTBOX.createMarkup(markup),
         TobagoClass.TREE_LISTBOX.createDefaultMarkups(tree));
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, tree);
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeNodeRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeNodeRenderer.java
index b096ae2..bb717e2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeNodeRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeNodeRenderer.java
@@ -28,6 +28,7 @@ import org.apache.myfaces.tobago.internal.component.AbstractUITreeListbox;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeMenu;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.model.Selectable;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -117,6 +118,16 @@ public class TreeNodeRenderer extends RendererBase {
     final String parentId = data.getRowParentClientId();
     final boolean visible = data.isRowVisible();
     final boolean folder = node.isFolder();
+    Markup markup = Markup.NULL;
+    if (data instanceof AbstractUITree && data.getSelectedState().isSelected(node.getPath())) {
+      markup = markup.add(Markup.SELECTED);
+    }
+    if (folder) {
+      markup = markup.add(Markup.FOLDER);
+      if (data.getExpandedState().isExpanded(node.getPath())) {
+        markup = markup.add(Markup.EXPANDED);
+      }
+    }
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
@@ -126,23 +137,15 @@ public class TreeNodeRenderer extends RendererBase {
       //        writer.writeAttribute(HtmlAttributes.value, node.getValue().toString(), true); // XXX converter?
       writer.writeAttribute(HtmlAttributes.VALUE, clientId, true);
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
       writer.writeAttribute(HtmlAttributes.SELECTED, folder);
     } else {
       writer.startElement(HtmlElements.DIV);
 
       // div id
       writer.writeIdAttribute(clientId);
+      writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
 
-      Markup markup = Markup.NULL;
-      if (data instanceof AbstractUITree && data.getSelectedState().isSelected(node.getPath())) {
-        markup = markup.add(Markup.SELECTED);
-      }
-      if (folder) {
-        markup = markup.add(Markup.FOLDER);
-        if (data.getExpandedState().isExpanded(node.getPath())) {
-          markup = markup.add(Markup.EXPANDED);
-        }
-      }
       // In the case of a sheet, we need not hiding the node, because the whole TR will be hidden.
       final boolean hidden = !dataRendersRowContainer && !visible;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRenderer.java
index a3caf42..e5fd2fb 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRenderer.java
@@ -20,9 +20,11 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UITreeNode;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.component.AbstractUITree;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.model.ExpandedState;
 import org.apache.myfaces.tobago.model.Selectable;
@@ -73,9 +75,10 @@ public class TreeRenderer extends RendererBase {
   @Override
   public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
 
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
     final AbstractUITree tree = (AbstractUITree) component;
-
     final String clientId = tree.getClientId(facesContext);
+    final Markup markup = tree.getMarkup();
     final UIComponent root = ComponentUtils.findDescendant(tree, UITreeNode.class);
     if (root == null) {
       LOG.error("Can't find the tree root. This may occur while updating a tree from Tobago 1.0 to 1.5. "
@@ -83,15 +86,14 @@ public class TreeRenderer extends RendererBase {
       return;
     }
 
-    final TobagoResponseWriter writer = getResponseWriter(facesContext);
-
     writer.startElement(HtmlElements.DIV);
+    writer.writeIdAttribute(clientId);
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.TREE,
-        TobagoClass.TREE.createMarkup(tree.getMarkup()),
+        TobagoClass.TREE.createMarkup(markup),
         TobagoClass.TREE.createDefaultMarkups(tree),
         tree.getCustomClass());
-    writer.writeIdAttribute(clientId);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, tree);
     writer.writeAttribute(DataAttributes.SCROLL_PANEL, Boolean.TRUE.toString(), false);
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java
index f0c7f08..5d107ef 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java
@@ -20,6 +20,7 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UITreeSelect;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeListbox;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
@@ -31,6 +32,7 @@ import org.apache.myfaces.tobago.model.Selectable;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
@@ -82,21 +84,21 @@ public class TreeSelectRenderer extends RendererBase {
   @Override
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
-    final UITreeSelect select = (UITreeSelect) component;
-    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(select, AbstractUITreeNodeBase.class);
+    final UITreeSelect treeSelect = (UITreeSelect) component;
+    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(treeSelect, AbstractUITreeNodeBase.class);
     final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
     if (data instanceof AbstractUITreeListbox) {
-      writer.write(StringUtils.defaultString(select.getLabel()));
+      writer.write(StringUtils.defaultString(treeSelect.getLabel()));
       return;
     }
 
-    final String id = select.getClientId(facesContext);
-    final String currentValue = getCurrentValue(facesContext, select);
+    final String id = treeSelect.getClientId(facesContext);
+    final String currentValue = getCurrentValue(facesContext, treeSelect);
     final boolean checked;
-    if (select.isValueStoredInState()) {
+    if (treeSelect.isValueStoredInState()) {
       checked = data.getSelectedState().isSelected(node.getPath());
     } else {
       checked = "true".equals(currentValue);
@@ -106,13 +108,15 @@ public class TreeSelectRenderer extends RendererBase {
     final Selectable selectable = data.getSelectable();
 
     writer.startElement(HtmlElements.SPAN);
+    final Markup markup = treeSelect.getMarkup();
+    writer.writeAttribute(DataAttributes.MARKUP, JsonUtils.encode(markup), false);
     writer.writeClassAttribute(
         TobagoClass.TREE_SELECT,
-        TobagoClass.TREE_SELECT.createMarkup(select.getMarkup()),
-        TobagoClass.TREE_SELECT.createDefaultMarkups(select));
-    HtmlRendererUtils.writeDataAttributes(facesContext, writer, select);
+        TobagoClass.TREE_SELECT.createMarkup(markup),
+        TobagoClass.TREE_SELECT.createDefaultMarkups(treeSelect));
+    HtmlRendererUtils.writeDataAttributes(facesContext, writer, treeSelect);
 
-    if (select.isShowCheckbox()
+    if (treeSelect.isShowCheckbox()
         && selectable != Selectable.none
         && (!selectable.isLeafOnly() || !folder)) {
       writer.startElement(HtmlElements.INPUT);
@@ -125,20 +129,21 @@ public class TreeSelectRenderer extends RendererBase {
         writer.writeNameAttribute(id);
       }
       writer.writeAttribute(HtmlAttributes.VALUE, id, false);
+      // TODO: ID must be at the outer tag
       writer.writeIdAttribute(id);
       writer.writeAttribute(HtmlAttributes.CHECKED, checked);
 
-      writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
+      writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, treeSelect)));
 
       writer.endElement(HtmlElements.INPUT);
     }
 
     // label
-    final String label = select.getLabel();
+    final String label = treeSelect.getLabel();
     if (StringUtils.isNotEmpty(label)) {
       writer.startElement(HtmlElements.LABEL);
       writer.writeClassAttribute(TobagoClass.TREE_SELECT__LABEL);
-      final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, select);
+      final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, treeSelect);
       if (title != null) {
         writer.writeAttribute(HtmlAttributes.TITLE, title, true);
       }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java
index 11d9a8e..0c5cc7d 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java
@@ -20,6 +20,7 @@
 package org.apache.myfaces.tobago.internal.util;
 
 import org.apache.myfaces.tobago.component.ClientBehaviors;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.context.DateTimeI18n;
 import org.apache.myfaces.tobago.internal.renderkit.Collapse;
 import org.apache.myfaces.tobago.internal.renderkit.Command;
@@ -289,4 +290,23 @@ public class JsonUtils {
     }
     return result;
   }
+
+  public static String encode(final Markup markups) {
+    if (markups == null || markups.isEmpty()) {
+      return null;
+    }
+    StringBuilder builder = new StringBuilder(20);
+    builder.append('[');
+    for (String markup : markups) {
+      builder.append('"');
+      builder.append(markup);
+      builder.append('"');
+      builder.append(',');
+    }
+    if (builder.length() > 1) {
+      builder.deleteCharAt(builder.length() - 1);
+    }
+    builder.append(']');
+    return builder.toString();
+  }
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
index ddd276e..ee08bb7 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
@@ -105,6 +105,11 @@ public enum DataAttributes implements MarkupLanguageAttributes {
   LEVEL("data-tobago-level"),
 
   /**
+   * Defines the markup of the component.
+   */
+  MARKUP("data-tobago-markup"),
+
+  /**
    * Defines a maximum value.
    */
   MAX("data-tobago-max"),
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/context/MarkupUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/context/MarkupUnitTest.java
index 922fcce..38eb42c 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/context/MarkupUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/context/MarkupUnitTest.java
@@ -40,7 +40,7 @@ public class MarkupUnitTest {
     Assert.assertArrayEquals(AB, toArray(Markup.valueOf("a,b").iterator()));
     
     Assert.assertArrayEquals(AB, toArray(Markup.valueOf("a, b").iterator()));
-    
+
     Assert.assertArrayEquals(AB, toArray(Markup.valueOf(", \ta , ,\n b ,").iterator()));
   }
   
@@ -148,6 +148,16 @@ public class MarkupUnitTest {
     Assert.assertFalse(ab.contains(Markup.valueOf("a,c,d,e,c,f,e,f")));
   }
 
+  @Test
+  public void testIsEmpty() {
+    final Markup a = Markup.valueOf("a");
+    final Markup ab = Markup.valueOf("a,b");
+
+    Assert.assertFalse(a.isEmpty());
+    Assert.assertFalse(ab.isEmpty());
+    Assert.assertTrue(Markup.NULL.isEmpty());
+  }
+
   public static Object[] toArray(final Iterator<?> iterator) {
     final List<Object> list = new ArrayList<Object>(10);
     while (iterator.hasNext()) {
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java
index 2255494..418a7ad 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java
@@ -23,6 +23,7 @@ import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.component.UIButton;
+import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
 import org.apache.myfaces.tobago.internal.config.AbstractTobagoTestBase;
 import org.apache.myfaces.tobago.internal.context.DateTimeI18n;
@@ -158,4 +159,19 @@ public class JsonUtilsUnitTest extends AbstractTobagoTestBase {
     Assert.assertEquals("[\"A-rập Xê-út (Tiếng A-rập)\"]", JsonUtils.encode(new String[]{"A-rập Xê-út (Tiếng A-rập)"}));
   }
 
+  @Test
+  public void encodeMarkup() {
+    final Markup a = Markup.valueOf("a");
+    final Markup ab = Markup.valueOf("a,b");
+
+    final String expectedA = "['a']".replaceAll("'", "\"");
+    final String expectedAb = "['a','b']".replaceAll("'", "\"");
+
+    Assert.assertEquals(expectedA, JsonUtils.encode(a));
+    Assert.assertEquals(expectedAb, JsonUtils.encode(ab));
+    Assert.assertEquals(null, JsonUtils.encode(Markup.NULL));
+    Assert.assertEquals(null, JsonUtils.encode((Markup) null));
+
+  }
+
 }

-- 
To stop receiving notification emails like this one, please contact
['"commits@myfaces.apache.org" <co...@myfaces.apache.org>'].