Hey guys,
Just want to say that I think Sage is amazing. Itās been making developing on WordPress an absolute joy from beginning to end. It will be my go to moving forward. The routing based system is awesome except in this moment right here
. For anyone using Barba JS version 2. I hopefully want this to be help for others. This took me a bit of getting used to.
Context
Because of Sageās routing system and Barbaās ajax calls to other pages, you run into a problem where once you get to the next page, you will see your elements but wonāt have the required CSS or JS run because of the body class. @philipp did an amazing job above using version 1 and this example I give is a continuation of it but for barba version 2.
1. Setting up a proper barba-container.
<div class="vendors-container" data-barba='wrapper'>
<div class="container" id="content-container" data-barba="container" data-barba namespace="one-pager">
<div id="body-classes" @php(body_class())>
...Put here the content you wish to change between pages...
</div>
</div>
</div>
Above, you will see that version 2 now requires attributes data-barba
and data-barba-namespace
. This is used similarly to @philippās example. Inside, you are creating an empty div that will hold the body classes of the body of the page you are transitioning to.
Tip: Make sure that the body_class
div has an ID rather than a class. I made the mistake of having it:
<div class="body-classes"></div>
The body_class()
function does not output anything if classes are already there⦠There is 30 minutes gone of my time lol.
2. Proper Initialization.
Before I had a barba v2 initialization in the common.js folder. Instead, I followed @philippās example and created it in assets/scripts/barbainit.js
. The code is here:
import barba from '@barba/core';
import anime from 'animejs';
export default function(routes) {
barba.init({
transitions: [
{
name: 'one-pager-transition',
to: {
namespace: ['one-pager'],
},
leave(data) {
return new Promise(resolve => {
jQuery(data.current.container).hide(function() {
anime({
// Animation details (I use anime.js but you could use GSAP here)
complete: function() {
// Callback function for when the animation is complete
// Barba JS v2 is promise based, so you need to call resolve() to move on to the enter part
resolve();
},
});
});
});
},
enter: ({ next }) => {
return new Promise(resolve => {
anime({
// animation parameters
complete: function() {
// Set new classes from #af-classes to body
jQuery('body').attr(
'class',
jQuery('#body-classes').attr('class')
);
// Fire routes again after new content loaded
routes.loadEvents();
resolve();
},
});
});
},
},
],
});
}
This is a redo of @philipp function but redone in Barba v2. We basically are taking the initialization method of barba v2 and exporting it as a function to put in the main.js file. If you are unaware of how this works have a look at the docs for BarbaJS. Basically, itās promise based, where once we get the new ācontainerā we are taking the body classes of that container that we did in the last step and applying to the body of the dom in itās current state. Then, we reinitialize the loadEvents()
method which triggers the routing based files of your choosing (CSS, JS etc).
3. Loading into your main.js file
Import:
import barbaInit from './barbainit';
Then plug er in to the loadEvents()
function.
jQuery(document).ready(() => {
routes.loadEvents();
barbaInit(routes);
});
Here itās loading the loadEvents
like Sage normally does but then triggers barbaInit
from the last step, which does the animation, replace the body with new body classes and reruns the loadEvents()
like it did a page refresh.
Excellent example by @philipp. Hopefully this has been a little helpful.
Code could be optimized more⦠considering that you will have to put a #body-classes
block in every template. You would also have to do step 2 for every single animation you do if you have more than one transition like I do lol.
Cheers.