DEV Community

Lawrence Fleming
Lawrence Fleming

Posted on

Hell is Wordpress: Part 1

Every dev has to do it. We all have to do one site with wordpress because that's what the client wants, and in all fairness it can be good for the portfolio because the dev that can beat a reasonable website out of the infinitely recursive birds nest that is an 18 year old blogging cms can probably find their feet in any situation, thus follows my many Sisyphean experiences of trying to square the circle and build a responsive, modern website out of twigs and bits of wire.

If you're not building a whole site off of the back of it, you're breaking your page into components and several of them will be javascript based. Js is now modular, package managed, asynchronous, cellular, modular, interactiveodular.

Yet Wordpress has been on the snooze while doing this. You don't integrate javascript into Wordpress, you sort of… hot glue it onto the side and hope it doesn't slide off.
Javascript? Isn't that the thing they use for alert boxes?
If you were to look at the oblique and monumental plugin industry that clings to the underside of wordpress like some sort of open source but not really remora fish, the word javascript is interchangeable with jQuery. I mean, why would you need anything else right?

jQuery still sitting pretty on such an ancient piece of software seems strangely fitting, but pragmatically it's bad.

It's fat, slow and all the other bad things you've heard about jQuery. Get it away from me.
So lets start using modern packages. Lets get some good libs in. How uhhh.. How do you do that? Well that's just easy! Wordpress employs a hooks system. For this process I'm integrating a delightfully lightweight and mobile friendly carrousel system called flickety which I do not mean to denigrate by making it stand next to wordpress.

It's a good bit of code and I enjoy it.

Ok. So we have to register the script, then enqueue the script in the loading stack and it all gets stuffed in a big messy file for everything in the site called functions.php which will inevitably become a huge multiline goliath full of duct tape and patch code. Woe betide anybody who needs to work with a functions.php of an older site.

function flickity_load(){
wp_register_script('flickity', get_template_directory_uri() . '/src/flickity/flickity.min.js', [], false, true);  wp_register_style('flickity_styling', get_template_directory_uri() . '/src/flickity/flickity.css')
}
Enter fullscreen mode Exit fullscreen mode

Ok so it's registered, what next. Ok now I enqueue it.

function flickity_load(){
  wp_register_script('flickity', get_template_directory_uri() . '/src/flickity/flickity.min.js', [], false, true);
  wp_register_style('flickity_styling', get_template_directory_uri() . '/src/flickity/flickity.css');
  wp_enqueue_script('flickity');
  wp_enqueue_style('flickity_styling')
}
Enter fullscreen mode Exit fullscreen mode

That's definitely code. With some nice empty parameters and some other crap. Still won't do anything though. Those aren't the hooks they're like.. hooks for the hooks. We'll get there.

Note: That last true is to place the script tag in the footer. It defaults to false. Why?

Ok now I need to instantiate the library. I'm going to instantiate the library off of multiple components but long story short I'm going to want something like this:

<script type="text/javascript">
const carousel = new Flickity('my-carousel', {...options...})
</script>
Enter fullscreen mode Exit fullscreen mode

Just a nice simple instantiation, we give it an element class to query and an object of options. But I want to be able to define what element it globs onto, I want to set what it calls the variable in case I have more than one carousel on one page and I want to be able to set the options. Which means passing variables from the server side theme layer to the browser side JS engine. Which means inline JS which means…

Inline JS Hell Level 2

Whenever I load a component which needs Flickity. I guess I'll add the code to trigger it. Which means actions. Actions are how hooks get.. hooked? So I build a template component and the first line of it is

do_action("component_has_carousel");
Enter fullscreen mode Exit fullscreen mode

And now we give it the hook in the functions file.

function component_has_carousel($args) {
  flickity_load();
}
add_action('component_has_carousel', 'component_has_carousel');
Enter fullscreen mode Exit fullscreen mode

Ok. So I load the library whenever the component is present. That's it right?

Right?!

No. So now I need to pass the parameters to this ever growing piece of code scattered around the file base. I can pass an argument variable with do_action(); So I guess I need to slap it all in an array and hope for the best.

do_action("component_has_carousel", 
  array(
    'element' => 'my-carousel',
    'name' => 'myCarousel',
    'options' => '
      wrapAround: true,
      setGallerySize: false,
      pageDots: false,'
    )
);
Enter fullscreen mode Exit fullscreen mode

Ew. Ok now we have to take those arguments and put it into javascript. Wait inline javascript? How do we do that? Oh you can't. First, we register a new piece of javascript using wp_add_inline_script, because inline javascript HAS to be attached to a registered piece of javascript (The funny thing is that this is a recent addition, for an age the only way to do this was to hack it in with a localisation hook). So we trundle back over to our old friend functions.php to enqueue a dummy script just so we can pin the inline code to it.

function component_has_carousel($args) {
  flickity_load();
  wp_register_script($args['name'],'',);
  wp_enqueue_script($args['name'], '',[], false, true);
}
Enter fullscreen mode Exit fullscreen mode

And now there's no more putting it off. We have to commit code blasphemy. We have to write js interpolated into php. It's ugly. It's unreadable. It's hacky as all hell.
It's Wordpress

function component_has_carousel($args) {
  flickity_load();
  wp_register_script($args['name'],'',);
  wp_enqueue_script($args['name'], '',[], false, true);
  wp_add_inline_script($args['name'], 
    'const '. $args['name'] .' = new Flickity(".' . $args['element'] 
    . '", {'.   $args['options'] .'});'
  );
}
Enter fullscreen mode Exit fullscreen mode

And to those of you who are still reading. What do we have to show for our efforts?

<script type="text/javascript" src="/wp-content/themes/theme/src/flickity/flickity.min.js?ver=5.8" id="flickity-js"></script>
<script type="text/javascript" id="my-carousel">
  const myCarousel = new Flickity( ".my-carousel", {
    wrapAround: true,
    setGallerySize: false,
    pageDots: false,
    }
  );
</script>
Enter fullscreen mode Exit fullscreen mode

Did you get all that? All that for two freaking script tags? This should not be difficult, this should not be so labyrinthine. This should not be so… Wordpress Pray for me dear reader. I have a long road to go before I'm done.

Discussion (1)

Collapse
ingosteinke profile image
Ingo Steinke • Edited on

While I find that even WordPress has improved a lot and they have a reasonable product roadmap for upcoming core development, this software remains tied to its past. In theory, you can use WordPress with PHP 5, and some people do so in practice, bound by some outdated plugins, while other plugins will break your whole site when you're below PHP 7.4.

Even worse, as a plugin developer, you might want to consider all of those cases, outdated core versions, outdated PHP versions, plugins depending on other plugins etc.

WordPress managed to ship a product that runs both ReactJS (in the backend for Gutenberg block editor) and jQuery (in the frontend, at least many sites do) at the same time, and you are free to extend, use and abuse it with plugins that you can place in the official store without risking a too critical review.

Thanks for the article! I like your writing style as well!