Sanity Check: Using data- attributes to pass to javascript?

I am building a Wordpress Gutenberg block based on the Lightgallery JS plugin, which uses a JSON object to initialize the gallery. I want to use PHP to create an element such as <div id="gallery-container" class="lcp-gallery inline" data-closable="false" data-container="gallery-container" data-dynamic="true" data-plugins="lgVideo,lgThumbnail" ..." and then have the javascript parse the data- attributes to initialize the gallery.

What I’m trying to avoid is to have to use PHP to echo out the javascript (since each gallery can have different settings).

Does this make sense? Is there anything wrong with doing it this way?

1 Like

I mean… “wrong”? no, it’ll work. Is it different than PHP echoing out the JSON? Not particularly. Unless the JS plugin can read the dataset, you’ll still have to have some javascript to construct the object from the attributes (In newer versions of ECMAscript, this can be as simple as a spread operator into an object though, so not exactly taxing).

I have another version of the same plugin that uses PHP to echo out the Javascript, and it’s… messy… Having a file with PHP, HTML, and JS in one file gives me vertigo, lol.

Essentially what I have now is an $attributes array, which includes some settings for the rendering, and some more to pass to the Lightgallery. I use PHP tweeze out the lightgallery-specific settings from the array, and then echo out a data-lgSettings=… JSON array. Then a bit of javascript to parse the gallery’s data-lgSettings attribute and initialize the gallery.

That actually makes a lot of sense and is a pretty clean approach. By using data- attributes, you’re keeping your PHP and JavaScript nicely separated, which is a good practice. It allows you to dynamically set up your galleries using PHP without hardcoding JavaScript for each instance.

When your JavaScript parses those data- attributes, it’s just reading the HTML that’s already been generated, so you avoid the messiness of echoing out JavaScript directly from PHP. Plus, this makes your code more maintainable and easier to tweak if you need to change settings later.

So, yeah, nothing wrong with this approach—it’s actually a solid way to do it! Just make sure your JavaScript is set up to properly read and handle all the possible data- attributes you might include for different galleries.

…eh…

IMO, it’s cleaner to have a JSON in the document than 20 or 30 dataSet attributes stuck on different elements scattered throughout the document. It’d be cleaner still to have javascript fetch the data when necessary, and not include it in the HTML OR the Javascript, but shrug. You do you.

1 Like

You might actually echo the JSON to a single data attribute. This way you don’t have excessive data-* attributes (that you need keep in sync when your data model changes), and you also don’t have PHP inside your actual JS (which will hopelessly derail any linter).

FWIW :-)

1 Like

I mean, you’d just feed the linter the output, not the preprocessed code. PHP should leave nothing behind that isnt valid javascript anyway…

But how would you lint JS that is getting generated at runtime? If you really need to dump JSON to JS variables, I guess you might have dedicated inline scripts doing nothing but declaring those variables… like e.g.

<script>
window._myVar = <?= json_encode($myVar) ?>
</script>

<script src="main.js">
// JS with actual logic, linted at build time
</script>

The downside is that you’d pollute the global namespace though. With data-* attributes OTOH you can have your gallery options scoped to their container HTML elements.

Grab the innetHTML of the script tag via the inspector? Look at it in view-source?
Remember - PHP isnt at runtime. It’s before runtime, from JS’s perspective.

in view-source is

<script>
window._myVar = { "data" : [ {"entry": "a thing"},{"entry":"another thing"} ] }
</script>

which no linter is going to balk at.

For the record, the only way that actually keeps the silos separate is for a separate Javascript file fetching (or equivalent XHR stuff) the data from PHP, and manipulating the DOM. Echoing data attributes into the HTML is mixing HTML and PHP; echoing an object into Javascript is mixing JS and PHP. Arguably, putting the script in a script tag mixes Javascript and HTML.

shrug It’s all about how much effort you want to expend in keeping things separate.

2 Likes

Well just to avoid confusion, linters are tools for static code analysis, not code generated dynamically per request. They will typically run as a pre-commit hook, or as a CI stage before deploying to a given environment, not while your code is actually getting served.

Just because you wouldn’t regularly run linters at that point, doesn’t mean you can’t.

For example you can also run your website throug the W3 validator, which one could argue is also a kind of linter.

1 Like

At the end everything else then developing a dynamically changing website in JavaScript is a “workaround”. When you need changes on a webpage without a complete reload you cannot do this with any other language without becoming unclean.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.