I am developing my first WordPress plugin for a simple quotation
I created settings pages at admin section those are working fine as I have not used any special css.
I have also created a public page where I have used bootstrap5 and fontawsome
but when it loads all its CSS is broken as default wordpress theme css also getting applied on it. it might be fixed for a specific theme, but is the theme is changed again it will be broken with new theme.
How can I handle this?
add_filter('the_content', array($this,'public_page'));
function public_page($content) {
if(is_page()){
$public_page_slug = get_option("alam_calc_slug",'alam-calc');
$current_page = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );
$slug = $current_page->post_name;
if( is_singular() &&
is_main_query() &&
$slug == $public_page_slug
) {
//this file has my custom page content including bootstrap.css.js and fontawsome
require_once dirname(__FILE__).'\inc\index.php';
return;
}
}
return $content;
}///end public_page()
You need to use the wp_enqueue_scripts action hook to load the custom styles on your front end.
Usage:
/**
* Load custom CSS and JavaScript.
*/
add_action( 'wp_enqueue_scripts', 'wpdocs_my_enqueue_scripts' );
function wpdocs_my_enqueue_scripts() : void {
// Enqueue my styles.
wp_enqueue_style( 'wpdocs-bootstrap-style', 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css' );
wp_enqueue_style( 'wpdocs-datatables-bootstrap-style', 'https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/css/dataTables.bootstrap4.min.css' );
// Enqueue my scripts.
wp_enqueue_script( 'wpdocs-bootstrap-bundle-script', 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.bundle.min.js', array(), null, true );
wp_enqueue_script( 'wpdocs-datatables-bootstrap-script', 'https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/js/dataTables.bootstrap4.min.js', array(), null, true );
wp_enqueue_script( 'wpdocs-jquery-datatables-script', 'https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/js/jquery.dataTables.min.js', array(), null, true );
}
Related
I'm developing my first WordPress plugin. I need to use a custom CSS for the settings pages that I created for the plugin but when I enqueue my stylesheet file, it affects the whole WordPress backend and not just my plugin's settings page.
Is possible to solve this problem? How?
When you want to add styles or scripts in WordPress you enqueue them using hooks. For the admin side the hook you are looking for is called admin_enqueue_scripts.
You can add something like
/**
* Register and enqueue a custom stylesheet in the WordPress admin.
*/
function wpdocs_enqueue_custom_admin_style() {
wp_register_style( 'custom_wp_admin_css', plugin_dir_url( __FILE__ ) . 'css/woo-solo-api-admin.css', false, '1.0.0' );
wp_enqueue_style( 'custom_wp_admin_css' );
}
add_action( 'admin_enqueue_scripts', 'wpdocs_enqueue_custom_admin_style' );
You just need to be careful to correctly specify the url of the css script you want to enqueue.
Hope this helps.
Oh and https://developer.wordpress.org page is great for finding out about WordPress functionality, core functions, hooks etc.
Also check out the plugin handbook: https://developer.wordpress.org/plugins/
Loads of useful information can be found there :)
EDIT:
admin_enqueue_scripts has a parameter you can use read more
/**
* Register and enqueue a custom stylesheet in the WordPress admin.
*/
function wpdocs_enqueue_custom_admin_style( $hook ) {
if ( $hook === 'edit.php' ) {
wp_register_style( 'custom_wp_admin_css', plugin_dir_url( __FILE__ ) . 'css/woo-solo-api-admin.css', false, '1.0.0' );
wp_enqueue_style( 'custom_wp_admin_css' );
}
}
add_action( 'admin_enqueue_scripts', 'wpdocs_enqueue_custom_admin_style' );
This will load the script only on the edit post screen.
You can see what hook is loaded on your screen by adding
error_log( print_r( $hook, true ) );
In your wpdocs_enqueue_custom_admin_style function before the condition. Enable the debug log in your wp-config.php and you'll get a name of your custom post screen hook.
Alternatively, you could target the $current_screen to match the CPT's screen. This will load the script only on that page.
When enqueueing a Wordpress child theme stylesheet the correct way the new styles override the parent's styles.
However, since Divi introduced Builder support for custom post types, a new stylesheet style-cpt.css has been added.
All the styles in this stylesheet (a lot of which unfortunately have !important after them) are declared after enqueued child styles, so will override any matching ones.
Is there any way of overriding such "custom" stylesheets?
The "remove_action(...);" solution no longer works as of Divi version 4.10.6 (Sept '21) as the "et_divi_replace_stylesheet" action was removed.
What I did to solve it was to overwrite line #776 (as of version 4.14.6) from Divi/includes/builder/core.php, so that the function et_builder_should_wrap_styles() always returns false:
function et_builder_should_wrap_styles() {
static $should_wrap = null;
if ( null === $should_wrap ) {
$post_id = get_the_ID();
// Warp on custom post type archives and on non-native custom post types when the builder is used.
$should_wrap = et_builder_is_custom_post_type_archive() || ( et_builder_post_is_of_custom_post_type( $post_id ) && et_pb_is_pagebuilder_used( $post_id ) );
}
// return $should_wrap; /*** ORIGINAL CODE ***/
return false; /*** NEW CODE ***/
}
Then to make sure I don't lose this edit when Divi updates, I set up an action to automatically rewrite this line every time a Divi update occurs:
add_action('upgrader_process_complete', 'edit_files_on_update'), 10, 2);
function edit_files_on_update($upgrader_object, $hook_extra) {
if ($hook_extra['action'] !== 'update') return false;
if ($hook_extra['type'] === 'theme' && isset($hook_extra['themes'])) {
// Divi - disable CPT CSS wrapper
if (array_search('Divi', $hook_extra['themes']) !== false) {
$file_location = get_template_directory().'/includes/builder/core.php';
$file_contents = file_get_contents($file_location);
$file_contents = str_replace('return $should_wrap;', 'return false;', $file_contents);
file_put_contents($file_location, $file_contents);
}
}
}
I know it's technically incorrect to edit a theme's original file, BUT the "correct" alternative is to overwrite the entire Divi/includes/builder/core.php file in my child theme, which is 7253 lines long! Chances are high that future Divi updates would edit that original file, leaving me without those edits reflected in the child theme version.
After some experimentation, I found that the following code in functions.php works... (please note, this will enqueue both the standard theme stylesheet as well as Divi's custom post child theme).
You can include all the styles you want to override in your own style-cpt.css file in your child theme folder.
function my_theme_enqueue_styles() {
$parent_style = 'divi-style';
$template_directory = get_template_directory_uri();
$stylesheet_directory = get_stylesheet_directory_uri();
wp_enqueue_style( $parent_style, $template_directory . '/style.css' );
wp_enqueue_style( 'child-style',
$stylesheet_directory . '/style.css',
array( $parent_style ),
wp_get_theme()->get('Version')
);
$parent_style = 'divi-cpt-style';
wp_enqueue_style( $parent_style, $template_directory . '/style-cpt.css' );
wp_enqueue_style( 'child-cpt-style',
$stylesheet_directory . '/style-cpt.css',
array( $parent_style ),
wp_get_theme()->get('Version')
);
}
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles' );
I am using this and is working fine:
function disable_cptdivi(){
remove_action( 'wp_enqueue_scripts', 'et_divi_replace_stylesheet', 99999998 ); } add_action('init', 'disable_cptdivi');
very late to the party but I managed to block the CPT styles from divi by prepending the #page-container selector to my Custom CSS in Theme Options, e.g.:
.header --> #page-container .header
#nav_toggle --> #page-container #nav_toggle
Will override the #et-boc selector
Tested with Divi 6.1.1
I'm working on a WordPress plugin which works perfectly if I insert the shortcode in a page or an article, but if I insert the shortcode in a widget area the .js and .css files aren't loaded.
//CUSTOM JS FUNCTIONS
add_action( 'wp_enqueue_scripts', 'my_functions' );
function my_functions() {
wp_register_script( 'my-script-1', plugin_dir_url( __FILE__ ) . 'js/functions.js', array( 'jquery' ), '1.0', true );
}
//CUSTOM CSS
add_action( 'wp_enqueue_scripts', 'my_css' );
function my_css() {
wp_register_style('my-css', plugin_dir_url( __FILE__ ) . 'css/style.css' );
}
//INCLUDE JS IF SHORTCODE EXIST
add_action( 'wp_print_styles', 'form_my_include' );
function form_my_include() {
global $post;
if (strstr($post->post_content, 'my_form_shortcode')) {
wp_enqueue_script('my-script-1');
wp_enqueue_style('my-css');
}
}
//SHORTCODE
function my_shortcode_add(){
ob_start();
include("include/my_function.php");
return ob_get_clean();
}
add_shortcode('my_shortcode', 'my_shortcode_add');
// Enable shortcodes in text widgets
add_filter('widget_text', 'do_shortcode');
You need to enqueue your script and stylesheet directly inside the shortcode. You can also load both the script and stylesheet inside the same wp_enqueue_scripts() hook.
//CUSTOM JS FUNCTIONS
add_action( 'wp_enqueue_scripts', 'my_scripts_and_stylesheets' );
function my_scripts_and_stylesheets() {
wp_register_script( 'my-script-1', plugin_dir_url( __FILE__ ) . 'js/functions.js', array( 'jquery' ), '1.0', true );
wp_register_style('my-css', plugin_dir_url( __FILE__ ) . 'css/style.css' );
}
//SHORTCODE
function my_shortcode_add(){
wp_enqueue_script('my-script-1'); //loaded here
wp_enqueue_style('my-css'); //loaded here
ob_start();
include("include/my_function.php");
return ob_get_clean();
}
add_shortcode('my_shortcode', 'my_shortcode_add');
// Enable shortcodes in text widgets
add_filter('widget_text', 'do_shortcode');
Your current code grabs to content inside post, and checks for the shortcode in there. Depending on where your shortcode is called, it might not actually be present in the post content, despite being present on the page.
By adding the wp_enqueue_script() & wp_enqueue_style() to your shortcode function, it will enqueue your whenever your shortcode is present on a page, regardless of where on the page it is.
Add this code to your plugin.
// Enable shortcodes in text widgets
add_filter('widget_text','do_shortcode');
This code simply adds a new filter allowing shortcodes to run inside widget.
Recently I found the following javascript from another thread on this forum;
var $content=$('div.leg_ol');
var $links=$('.leg_test').hover(function(){
var index= $links.index(this);
$content.stop(true,true).hide().eq(index).fadeIn();
},function(){
$content.stop(true,true).hide().eq(index);
});
(I would link to the OP, but unfortunately have lost the page).
JSFIDDLE: https://jsfiddle.net/mfyctwvs/1/
The code does exactly what I want to do - in theory, now I am pretty much completely new to js, so this is a very tricky area for me - please bear with me on this.
When I post the code in functions.php it causes my whole site to stop working, I assume because it cannot read it or there is some conflict?
So my first thought, looking at jsfiddle was the js version and that it is specified as no wrap in . If I change either of these the code does not work.. ..so 1. Am I making a newb mistake trying to include incompatible js in my functions.php (probably yes?) & 2. is there a straightforward change I can make to get this working in my functions.php?
I have been searching on this for hours & am sure that I could get this working with some adjustments?
FYI; Functions.php
<?php// Set path to WooFramework and theme specific functions
$functions_path = get_template_directory() . '/functions/';
$includes_path = get_template_directory() . '/includes/';
// Don't load alt stylesheet from WooFramework
if ( ! function_exists( 'woo_output_alt_stylesheet' ) ) {
function woo_output_alt_stylesheet () {}
}
// WooFramework
require_once ( $functions_path . 'admin-init.php' ); // Framework Init
if ( get_option( 'woo_woo_tumblog_switch' ) == 'true' ) {
//Enable Tumblog Functionality and theme is upgraded
update_option( 'woo_needs_tumblog_upgrade', 'false' );
update_option( 'tumblog_woo_tumblog_upgraded', 'true' );
update_option( 'tumblog_woo_tumblog_upgraded_posts_done', 'true' );
require_once ( $functions_path . 'admin-tumblog-quickpress.php' ); // Tumblog Dashboard Functionality
}
/*-----------------------------------------------------------------------------------*/
$includes = array(
'includes/theme-options.php', // Options panel settings and custom settings
'includes/theme-functions.php', // Custom theme functions
'includes/theme-actions.php', // Theme actions & user defined hooks
'includes/theme-comments.php', // Custom comments/pingback loop
'includes/theme-js.php', // Load JavaScript via wp_enqueue_script
'includes/theme-plugin-integrations.php', // Plugin integrations
'includes/sidebar-init.php', // Initialize widgetized areas
'includes/theme-widgets.php', // Theme widgets
'includes/theme-advanced.php', // Advanced Theme Functions
'includes/theme-shortcodes.php', // Custom theme shortcodes
'includes/woo-layout/woo-layout.php', // Layout Manager
'includes/woo-meta/woo-meta.php', // Meta Manager
'includes/woo-hooks/woo-hooks.php' // Hook Manager
);
// Allow child themes/plugins to add widgets to be loaded.
$includes = apply_filters( 'woo_includes', $includes );
foreach ( $includes as $i ) {
locate_template( $i, true );
}
// Load WooCommerce functions, if applicable.
if ( is_woocommerce_activated() ) {
locate_template( 'includes/theme-woocommerce.php', true );
}
/*-----------------------------------------------------------------------------------*/
/* You can add custom functions below */
/*-----------------------------------------------------------------------------------*/
add_action( 'init', 'woo_custom_move_navigation', 10 );
function woo_custom_move_navigation () {
// Remove main nav from the woo_header_after hook
remove_action( 'woo_header_after','woo_nav', 10 );
// Add main nav to the woo_header_inside hook
add_action( 'woo_header_inside','woo_nav', 10 );
} // End woo_custom_move_navigation()
/* Testing stuff for mobile */
function woo_load_responsive_meta_tags () {
$html = '';
$html .= "\n" . '<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame -->' . "\n";
$html .= '<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />' . "\n";
echo $html;
} // End woo_load_responsive_meta_tags()
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'user-scripts',
get_template_directory_uri() . '/functions/user-scripts.js',
array('jquery') // any script dependancies. i.e. jquery
);
});
?>
In wordpress you in ject your javascript files into your theme using the wordpress api/hooks. the method you want is wp_enqueue_script. Here are the docs
It's used like this:
add_action('wp_enqueue_scripts', 'addScript');
function addScript() {
wp_enqueue_script(
'script-name',
get_template_directory_uri() . '/path-to-your-script.js',
array('jquery') // any script dependancies. i.e. jquery
);
}
Depending on the version of php you have, you can inline the function:
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'script-name',
get_template_directory_uri() . '/path-to-your-script.js',
array('jquery') // any script dependancies. i.e. jquery
);
});
From the script provided by #atmd the following code worked.
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'script-name',
get_template_directory_uri() . '/path-to-your-script.js',
array('jquery') // any script dependancies. i.e. jquery
);
});
A precondition required was that the script was located in the /functions/ folder of the theme used. The original code posted works perfectly on the site.
Within a wp plugin, I see the following code on the php file of the plugin.
public function register_plugin_scripts() {
/*** Styles ***/
$cyclone_css = add_query_arg(array('cyclone_templates_css' => 1), home_url( '/' ));
wp_register_style( 'cyclone-slider-plugin-styles', $cyclone_css );//contains our combined css from ALL templates
wp_enqueue_style( 'cyclone-slider-plugin-styles' );
/*** Scripts ***/
wp_register_script( 'cycle', $this->plugin_url.'js/jquery.cycle.all.min.js', array('jquery') );
wp_enqueue_script( 'cycle' );
}
Now, I want to alter some of it. Right now, this plugin is used at every single page. Implying both the 1) combined css 2) jquery.cycle.all.min.js is requested each page. However, I only use this plugin for the main page. So how do I fix it, making the css file + js to only be loaded for the main page, nothing else.
Next, I do not want to combine css from all templates. Instead, it should be pinpointed to a selected location. How to do that?. Thanks in advance. Plugin is Cyclone Slider 2.
If you were happy to edit the plugin code directly, it would be a simple matter of making the wp_enqueue_script() calls conditional on being on the home page.
public function register_plugin_scripts() {
/*** Styles ***/
$cyclone_css = add_query_arg(array('cyclone_templates_css' => 1), home_url( '/' ));
wp_register_style( 'cyclone-slider-plugin-styles', $cyclone_css );//contains our combined css from ALL templates
/*** Scripts ***/
wp_register_script( 'cycle', $this->plugin_url.'js/jquery.cycle.all.min.js', array('jquery') );
if (is_front_page()){
wp_enqueue_style( 'cyclone-slider-plugin-styles' );
wp_enqueue_script( 'cycle' );
}
}
However, you almost certainly don't want to edit the plugin, because your changes will get overwritten when the plugin is updated.
I would therefore use wp_dequeue_script and wp_dequeue_style to get stop the scripts loading where you don't want them to.
Per Wordpress Function reference, you could add this code in your theme function.php file or similar:
/**
* Dequeue a queued script.
*
* Hooked to the wp_print_scripts action, with a late priority (100),
* so that it is after the script was enqueued.
*/
function wpcyclone_dequeue_script() {
wp_dequeue_script( 'cycle' );
wp_dequeue_script( 'cyclone-slider-plugin-styles' );
}
if (!is_front_page()){
add_action( 'wp_print_scripts', 'wpcyclone_dequeue_script', 100 );
}