Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing HTML data attributes #207

Open
lief-erickson opened this issue Jul 11, 2024 · 4 comments
Open

Passing HTML data attributes #207

lief-erickson opened this issue Jul 11, 2024 · 4 comments

Comments

@lief-erickson
Copy link

lief-erickson commented Jul 11, 2024

Looking for some guidance about best practices.

Within the context of this plugin or any of its related plugins, is there a general mechanism to pass data-attributes, perhaps through @otherprops, similar to what is done with parallax or from the dita-bootstrap.extension plugin?

This is the target HTML we're attempting to get:

<span data-fancy-text='{ "effect": "slide", "direction": "right", "color": "#ffe400", 
"speed": 100, "string": ["some", "fancy", "text"], "duration": 2500 }'>some fancy text</span>

and

<div data-anime='{ "el": "childs", "translateY": [30, 0], "opacity": [0,1], "duration": 600, 
"delay": 0, "staggervalue":200, "easing": "easeOutQuad" }'>
:
:
</div>

Notice that the @data-* values are JSON, which is not possible to put into @otherprops. Instead of @otherprops, what if <data> was used?

<ph otherprops="data-fancy-text">
     <data>'{ "effect": "slide", "direction": "right", "color": "#ffe400", 
     "speed": 100, "string": ["some", "fancy", "text"], "duration": 2500 }'</data>
      some fancy text</ph>

<div otherprops="data-anime">
     <data>'{ "el": "childs", "translateY": [30, 0], "opacity": [0,1], "duration": 600, 
      "delay": 0, "staggervalue":200, "easing": "easeOutQuad" }'</data>
:
:
</div>

Aside: @otherprops is not allowed on <title>.

@lief-erickson
Copy link
Author

lief-erickson commented Jul 11, 2024

Here's my current thought. It works for <ph> but not for <div>. It needs to be a a general or generic-enough solution that would work for any element.

<xsl:template match="*[@otherprops][data]" mode="otherprops-attributes">
<xsl:variable name="attributeName" select="@otherprops"/>

<xsl:attribute name="{$attributeName}">
<xsl:value-of select="data"/>
</xsl:attribute>
<xsl:value-of select="text()"/>

</xsl:template>

Sometimes posting on the interwebs helps work through the problem.

This appears to work in a variety of situations. Feedback appreciated, especially from @jason-fox and/or @infotexture.

  <xsl:template match="*[@otherprops][data]" mode="commonattributes">
    <xsl:variable name="attributeName" select="@otherprops"/>
    <xsl:attribute name="{$attributeName}">
      <xsl:value-of select="data"/>
    </xsl:attribute>
  </xsl:template>

If this is a good approach, could it be easily extended to additional Bootstrap components or features not yet part of this family of plugins?

My quibble is now the JSON in the HTML is rendered with &#34; rather than ".

{ &#34;effect&#34;: &#34;slide&#34;, &#34;direction&#34;: &#34;right&#34;, &#34;color&#34;: &#34;#ffe400&#34;, &#34;speed&#34;: 100, &#34;duration&#34;: 2500 }

@jason-fox
Copy link
Collaborator

jason-fox commented Jul 13, 2024

My quibble is now the JSON in the HTML is rendered with " rather than ".

Just use disable-output-escaping="yes"

<xsl:template match="*[@otherprops][data]" mode="commonattributes">
    <xsl:variable name="attributeName" select="@otherprops"/>
    <xsl:attribute name="{$attributeName}">
      <xsl:value-of select="data" disable-output-escaping="yes" />
    </xsl:attribute>
</xsl:template>

If you are worrying specifically about &#34; - you can't easily deal with this as you can't place an unescaped quote inside a quoted attribute.

@jason-fox
Copy link
Collaborator

In your case I would probably just create a specialism of the <data> element - you could set the name of the attribute to match the attribute you want to create and legitimately use props to define the type of processing to be done.

<ph>
  <data name="data-anime" props="data-attribute">
    { "el": "childs", "translateY": [30, 0], "opacity": [0,1], "duration": 600,
      "delay": 0, "staggervalue":200, "easing": "easeOutQuad" }
   </data>
    Text goes here....
</ph>

Something like this:

<xsl:template match="*[contains(@class, ' topic/data ') and contains(@props, 'data-attribute')]">
    <xsl:attribute name="@name">
      <xsl:value-of select="." disable-output-escaping="yes" />
    </xsl:attribute>
</xsl:template>

@jason-fox
Copy link
Collaborator

I tend to use otherprops because my attributes are simple key-values and compared to something like:

<section outputclass="parallax py-6 px-4 text-white">
  <data name="data-img-src" props="data-attribute">...</data>
  <data name="data-speed" props="data-attribute">0.3</data>
  Text goes here ...
</section>  

I think combining all the data-attributes in one place is shorter and easier to read:

<section outputclass="parallax py-6 px-4 text-white" otherprops="data-img-src(...) data-speed(0.3)">
  Text goes here ...
</section>  

I suppose it would be possible to amend existing templates to cover something like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants