Add support for HTML5 style attributes (data-dt-*) in the Thymeleaf dialect

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Add support for HTML5 style attributes (data-dt-*) in the Thymeleaf dialect

cordin
Hi dandelion team,

Thymeleaf has additional support for the use of HTML5 style attributes (data-dt-*) instead of the usual namespace ones (dt:*). This, at first, is independent of any dialect, as the Thymeleaf core extracts the atribute names and values by itself to call the dialects.

But it doesn't work in some cases with the dandelion datatables dialect. See https://github.com/dandelion/dandelion-datatables/issues/310

The problem seems to be related to some processors, which validate that the parent node contains attributes in the dt:* form. Ex (DivConfTypeAttrProcessor):

   private void checkMarkupUsage(Element element) {
      Element parent = (Element) element.getParent();

      if (parent == null || !"div".equals(parent.getNormalizedName())
            || !parent.hasAttribute(DataTablesDialect.DIALECT_PREFIX + ":conf")
            || StringUtils.isBlank(parent.getAttributeValue(DataTablesDialect.DIALECT_PREFIX + ":conf"))) {
         throw new DandelionException(
               "The element 'div dt:confType=\"...\"' must be inside an element 'div dt:conf=\"tableId\"'.");
      }
   }


I would like to add the support for the HTML5 style attributes (data-dt-*) by myself. As this code will be repeated in some places, I'm planning to add some static methods to the DataTablesDialect class and replace the current implementation of the checkMarkupUsage methods to use the new static methods. As an example, I would add the following methods to the DatatablesDialect class:

        public static String getXMLDatatablesAttribute(String action) {
                return DIALECT_PREFIX + ":" + action;
        }

        public static String getHTML5DatatablesAttribute(String action) {
                return "data-" + DIALECT_PREFIX + "-" + action;
        }

        private static boolean hasAttribute(Element element, String attribute) {
                return (element.hasAttribute(attribute) && !StringUtils.isBlank(element.getAttributeValue(attribute)));
        }

        public static boolean hasDatatablesAttribute(Element element, String action) {
                return hasAttribute(element, getXMLDatatablesAttribute(action))
                                || hasAttribute(element, getHTML5DatatablesAttribute(action));
        }


Then, the previous checkMarkupUsage would be implemented like this:

   private void checkMarkupUsage(Element element) {
      Element parent = (Element) element.getParent();

      if (parent == null || !"div".equals(parent.getNormalizedName())
            || !DataTablesDialect.hasDatatablesAttribute(parent, "conf")) {
         throw new DandelionException(
               "The element 'div dt:confType=\"...\"' or 'div data-dt-confType=\"...\"' must be inside an element 'div dt:conf=\"tableId\"' or 'div data-dt-conf=\"tableId\"'.");
      }
   }


I you agree with the solution I will implement it and send the related pull requests ASAP.