I'm having trouble removing (wp_dequeue_style) all the stylesheets loaded in a WP site.
I want to remove all the styles loaded, with the purpose of recreating a new style that can be better controlled and optimized and reduce 68 requests to 1.
But before I get further into this, I'll say a bit about the tools used.
I'm using Wordpress v5.4.1 on a server with Apache 7.2.30. The WP theme is MasterStudy Child and the plugins used are as follows:
Breadcrumb NavXT
BuddyPress
Contact Form 7
GamiPress
GTmetrix for WordPress
WPBakery Page Builder
MasterStudy LMS Learning Management System PRO
MasterStudy LMS
Paid Memberships Pro
Slider Revolution
GDPR Compliance & Cookie Consent
STM Configurations
Transients Manager
UpdraftPlus - Backup/Restore
WooCommerce
WordPress Importer
WP Reset
Query Monitor
I can get a list of all enqueued CSS stylesheets using 3 methods:
1. Chrome Inspector - Network tab
2. Query Monitor
3. The script bellow, used in functions.php of parent theme
function remove_theme_head_styles() {
global $wp_styles;
echo "<h2>Enqueued CSS Stylesheets</h2>";
foreach( $wp_styles->queue as $handle ) :
echo $handle . ", ";
endforeach;
}
add_action( 'wp_enqueue_scripts', 'remove_theme_head_styles', 9000 );
The results are as follows:
Method 1 (Chrome): 68 requests, though some are duplicates
Method 2 (Query Monitor): 66 Styles
Method 3 (php script): 52 results
Next, lets switch from listing all the enqueued CSS files, to removing them with this script
function remove_theme_head_styles() {
global $wp_styles;
foreach( $wp_styles->queue as $handle ) :
wp_dequeue_style( $handle );
wp_deregister_style( $handle );
endforeach;
}
add_action( 'wp_enqueue_scripts', 'remove_theme_head_styles', 9000 );
Let's see what we have now:
Method 2 (Query Monitor): 13 styles - all of them loaded in the footer. 10 of them are coming from the parent theme and the other 3 from the theme's main plugin MasterStudy LMS
Method 1 (chrome): 14 requests, same as QM except for 1 extra font family CSS
Method 3 (php script echo): 0 results
So, maybe we need to change the hook, go further down the hooks order, to also include the stylesheets enqueued in the footer.
Let's try wp_print_footer_scripts with a big number for priority
add_action( 'wp_print_footer_scripts', 'remove_theme_head_styles', 9000 );
The results are:
Method 1 (chrome): 65 requests, WTF? almost all of them have loaded!
Method 2 (Query Monitor): 0 Styles
Method 3 (php script): 0 results - same hook used for listing, wp_print_footer_scripts
And YES the webpage has rendered accordingly, so the Chrome Inspector is not wrong, but this doesn't mean that the other 2 methods have false results. It just means that the CSS files are re-enqueued after the results of methods 2 and 3 are generated
But how is this happening I cannot understand.
I have also tried splitting the removal process into 2 hooks, 1 with wp_enqueue_scripts and another with different hooks like wp_footer and such, but with no success
The 10 'trouble' styles coming from the theme itself, are loaded with this function
themes/masterstudy/inc/custom.php
function stm_module_styles($handle, $style = 'style_1', $deps = array(), $inline_styles = '')
{
$path = get_template_directory_uri() . '/assets/css/vc_modules/' . $handle . '/' . $style . '.css';
$handle = 'stm-' . $handle . '-' . $style;
wp_enqueue_style($handle, $path, $deps, STM_THEME_VERSION, 'all');
if (!empty($inline_styles)) wp_add_inline_style($handle, $inline_styles);
}
Here's an example of using the function above
themes/masterstudy/vc_templates/stm_mailchimp.php
stm_module_styles('mailchimp', 'style_1', array(), $inline_styles);
Obviously, if I comment that line then the CSS won't be loaded, but this is not the approach I want to take to solving the problem.
So, if anyone can offer some help, it would be much appreciated
Thanks for taking the time and reading through this
The below is likely not a great approach, but I recently needed to prevent VC from loading the free version of FontAwesome (I use the pro version in my theme) and no amount of dequeue/deregister would work - the below is the only way I could stop it loading (without editing files outside my theme).
The thing that actually worked, was brutally unsetting the entry in wp_styles.
function hack_dequeue_fa() {
global $wp_styles;
$remove = array(
'vc_font_awesome_5',
'vc_font_awesome_5_shims',
);
foreach($remove as $handle) {
wp_dequeue_style($handle);
wp_deregister_script($handle);
unset($wp_styles->registered[$handle]);
}
}
add_filter( 'wp_enqueue_scripts', 'hack_dequeue_fa', PHP_INT_MAX );
Related
I create a site based on Typo3 9.5.12 / Bootstrap Package 11.0.2.
I need to enable my editors to select a backend layout for new pages (!).
So far I did not find a way to do so. Setting Page TSConfig for the editors group like so gives me the following result:
page.TCEFORM {
pages {
abstract.disabled = 1
backend_layout.disabled = 0
backend_layout_next_level.disabled = 0
}
}
Abstract field is disabled as expected.
Backend Layout cannot be selected. What can I do?
Have you granted access to these fields in the BE-Group definition?
I know how to load external js files to Vue.js or Nuxt.js but I have a specific problem with eg. french Shom Widget files.
Shom (for tides predictions) give access to a widget via a js file containing a lot of dirty document.write (you can see a sample at https://services.data.shom.fr/hdm/vignette/grande/CAP_FERRET?locale=fr)
var rid="vignette_shom_"+Math.round(Math.random()*10000000);
document.write("<iframe width='675' id='"+rid+"' height='900' frameborder='0' scrolling='no'></iframe>");var ifrm = document.getElementById(rid);ifrm = (ifrm.contentWindow) ? ifrm.contentWindow : (ifrm.contentDocument.document) ? ifrm.contentDocument.document:ifrm.contentDocument;ifrm.document.open();
ifrm.document.write('<!DOCTYPE html>');ifrm.document.write('<html>');ifrm.document.write('<head>');
.. ans so on...
Trying to load this script into the mounted method is ok, but i'm unable to display content into component.
Any idea ?
thanks
Hi guys ,
I'm currently working on a Drupal project which use the Panelizer module by overriding the default node display. The panel for this content type is made width a lot of rules and specifications in order to display some specific content (like views) according some fields.
Now I need to print in PDF the same content that is displayed by the panelizer module but in another display (in one column ), so I cloned the display I use and rearranged it to display what I want.Then I want to use this display width the print module but I didn't managed to do that.
Any idea how can I do that ?
I just can't use the default node render, because I would miss some informations dues to the specifications used in the panel, and I can't print the panelized content because it's not the same display.
I read this thread but how can I say to the print module to use the "print" display I cloned instead of the default one ?
Any suggestions or ideas will be appreciated or if you have another idea for doing that you're welcome :)
Thank you !
In your print pdf template you can load the node then create a view with the display and finally render it : drupal_render(node_view(node_load($node->nid), "name of your display")) ;
Another way is to alter node entity info, telling that 'print' view can be panelized, i.e.
/**
* Implements hook_entity_info_alter().
*/
function mymodule_entity_info_alter(&$entity_info) {
$entity_info['node']['view modes']['print']['custom settings'] = TRUE;
...
}
After that, you go to panelizer settings of your content type(s), and set whatever you want for the print view mode
I try to write a link from a first page that will open a second page that includes prettyphoto and automaticaly open the prettyphoto plugin including a third page. Doing that, I've got to transmit a variable from the first link and retrieve it in the third.
Is it possible ?
Yes, it is: If the first an the third website were running on the same server you wil be able to use HTML5 Web Storage or Cookies. Here's an example (HTML5 Webstorage):
// Save...
localStorage.setItem('item', myVariable);
// Open...
var myVariable = localStorage.getItem('item');
I have found the following issue
I added a variable into the link of the first page
mypage.php?my_variable=<? echo $id; ?>
and on the second page, test the presence of this variable to implante an automatic launch of prettyphoto into the jQuery function init :
<?PHP
if(isset($_GET['my_variable'])) {
$id = $_GET['my_variable'];
?>
$.prettyPhoto.open('third_page.php?id=<?PHP echo $id; ?>&ie=UTF-8&oe=UTF-8& q=prettyphoto&iframe=true&width=100%&height=100%');
<?PHP
}
?>
I'm now looking for a full screen prettyphoto auto opening, but that's another problem, the main problem is solved for me.
I'm using the Like Box social plugin (https://developers.facebook.com/docs/reference/plugins/like-box/) and it works great.
Problem is that I'm using it within a Rails 4 application with Turbolinks. Whenever I reload a page, the like box shows up. If I click on any link, the next page loads and the Like Box doesn't show up.
I tried this already but didn't worked =/
http://reed.github.io/turbolinks-compatibility/facebook.html
Any ideas on how to solve this problem?
The link you have posted in original question is quite nice. It asks us to create three functions:
1) saveFacebookRoot: This is needed so that the div#fb-root can be restored at a later point. This is called upon page:fetch. page:fetch is called while the DoM is still of the old page. i.e: new page has not replaced the old page
2) restoreFacebookRoot: This is needed to that the div#fb-root can be appended back to the page. It is called on page:change. page:change is called when the new DoM is available.
3) There is minor typo in there. We need to call this in page:load
FB.XFBML.parse() // Correct
Instead of :
FB?.XFBML.parse() // InCorrect
Remember that when the page is first reloaded, only the page:change is called out of these three.
The trick here is the use of global variables fb_root and fb_events_bound. These must be accessible in all other pages, but this is the reason why we hate turbolinks in the first place.
References: http://reed.github.io/turbolinks-compatibility/facebook.html
Install observejs:
gem 'observejs'
Then add tag to the widget:
<div as="FB" class="fb-comments" data-href="<%= request.original_url %>"></div>
Then create a new script in javascripts folder (fb.coffee in my example):
ObserveJS.bind 'FB', class
root: document.createElement('div')
#::root.id = 'fb-root'
loaded: =>
if !document.body.contains(#root)
document.body.appendChild(#root)
if FB?
FB.XFBML.parse()
else
#initialize()
initialize: =>
js = document.createElement('script')
script = document.getElementsByTagName('script')[0]
js = document.createElement('script')
js.id = 'facebook-jssdk'
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=YOUR_APP_ID&version=VERSION_OF_API"
script.parentNode.insertBefore(js, script)
Include the js files in your application.js
//= require observejs
//= require fb