Last active
August 9, 2024 04:49
-
-
Save felipemarcos/21c7f93290e0ea4b5864ac9ec42c43d0 to your computer and use it in GitHub Desktop.
Breakdance - Loading a page with AJAX and initializing its scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Explanation: | |
* When rendering a Breakdance Page via ajax, we need to manually append the styles and scripts that are needed for the page to function properly. | |
* This is because Breakdance pages conditionally load their assets based on the page's content, and we can't predict which assets will be needed if we're loading the page via AJAX. | |
*/ | |
async function openQuickView() { | |
const body = new FormData(); | |
const postId = 2928; // The post ID you want to load via AJAX | |
body.append("action", "breakdance_quickview"); | |
body.append("postId", postId); | |
const { makeAjaxRequest } = window.BreakdanceFrontend.utils; | |
const response = await makeAjaxRequest(BreakdanceFrontend.data.ajaxUrl, { | |
method: "POST", | |
credentials: "same-origin", | |
body | |
}); | |
const { data } = await response.json(); | |
const styles = [...data.styles, ...data.postStyles]; | |
// Show the popup for demonstration purposes, you can remove this line | |
showMockPopup(); | |
if (data.html) { | |
// Do your thing with the response HTML | |
document.querySelector("#quick-view-content").innerHTML = data.html; | |
} | |
// Append scripts to the head | |
const scriptPromises = []; | |
if (data.scripts) { | |
data.scripts.forEach(scriptUrl => { | |
const scriptEle = document.createElement("script"); | |
scriptEle.src = scriptUrl; | |
const scriptPromise = new Promise((resolve, reject) => { | |
scriptEle.onload = resolve; | |
scriptEle.onerror = reject; | |
}); | |
document.head.appendChild(scriptEle); | |
scriptPromises.push(scriptPromise); | |
}); | |
} | |
// Append styles to the head | |
const stylePromises = []; | |
if (styles) { | |
styles.forEach(styleUrl => { | |
const linkEle = document.createElement("link"); | |
linkEle.rel = "stylesheet"; | |
linkEle.href = styleUrl; | |
const stylePromise = new Promise((resolve, reject) => { | |
linkEle.onload = resolve; | |
linkEle.onerror = reject; | |
}); | |
document.head.appendChild(linkEle); | |
stylePromises.push(stylePromise); | |
}); | |
} | |
// Wait for all scripts to load before running inline scripts | |
await Promise.all(scriptPromises); | |
await Promise.all(stylePromises); | |
// Append inline scripts to the body | |
if (data.inlineScripts) { | |
data.inlineScripts.forEach(scriptText => { | |
const scriptEle = document.createElement("script"); | |
scriptEle.textContent = scriptText; | |
document.body.appendChild(scriptEle); | |
}); | |
} | |
} | |
// Demonstration purposes only | |
function showMockPopup() { | |
document.querySelector("#quick-view-popup").style.display = "flex"; | |
} | |
function mockUI() { | |
const { isBuilder } = window.BreakdanceFrontend.utils; | |
if (isBuilder()) return; | |
document.body.insertAdjacentHTML( | |
"beforeend", | |
` | |
<div id="quick-view-popup"> | |
<div id="quick-view-content"></div> | |
</div> | |
<button id="quick-view-trigger">Open Quick View</button | |
`); | |
// Add inline styles for demonstration purposes | |
document.head.insertAdjacentHTML( | |
"beforeend", | |
` | |
<style> | |
#quick-view-popup { | |
position: fixed; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background-color: rgba(0, 0, 0, 0.5); | |
z-index: 9999; | |
display: none; | |
justify-content: center; | |
align-items: center; | |
} | |
#quick-view-content { | |
background-color: white; | |
padding: 20px; | |
border-radius: 5px; | |
max-width: 600px; | |
} | |
#quick-view-trigger { | |
margin: 50px; | |
} | |
</style> | |
` | |
); | |
} | |
// End of demonstration purposes only | |
document.addEventListener("DOMContentLoaded", () => { | |
// For demonstration purposes, we're adding a button to the body. Feel free to remove this code in your implementation. | |
mockUI(); | |
document | |
.querySelector('#quick-view-trigger') | |
.addEventListener('click', openQuickView); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Breakdance - Cool Quickview | |
* Description: Load an element via AJAX and initialize its scripts and styles. | |
* Version: 1.0 | |
* Author: Soflyy | |
*/ | |
use Breakdance\Render\ScriptAndStyleHolder; | |
add_action('breakdance_loaded', function () { | |
\Breakdance\AJAX\register_handler( | |
'breakdance_quickview', | |
'cool_quickview_load_breakdance_element_via_ajax', | |
'none', | |
false, | |
[ | |
'args' => [ | |
'postId' => FILTER_VALIDATE_INT | |
], | |
], | |
true | |
); | |
}); | |
function getPostsGeneratedCssFilePaths() { | |
$postsStyles = array_values(ScriptAndStyleHolder::getInstance()->getPostsGeneratedCssFilePaths()); | |
$flattened = []; | |
foreach ($postsStyles as $item) { | |
$flattened = array_merge($flattened, array_values($item)); | |
} | |
return $flattened; | |
} | |
function cool_quickview_load_breakdance_element_via_ajax() { | |
$postId = $_POST['postId'] ?? null; | |
$html = \Breakdance\Render\render($postId); | |
$dependencies = ScriptAndStyleHolder::getInstance()->dependencies; | |
$postStyles = getPostsGeneratedCssFilePaths(); | |
return [ | |
'data' => [ | |
'html' => $html, | |
'styles' => $dependencies['styles'] ?? [], | |
'postStyles' => $postStyles, | |
'scripts' => $dependencies['scripts'] ?? [], | |
'inlineScripts' => $dependencies['inlineScripts'] ?? [] | |
], | |
]; | |
} | |
function cool_quickview_enqueue_script() { | |
wp_enqueue_script( 'breakdance-quickview', plugin_dir_url( __FILE__ ) . 'main.js' ); | |
} | |
add_action('wp_enqueue_scripts', 'cool_quickview_enqueue_script'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment