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?
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.
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.
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).
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.
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.
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.
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.