I have the following pieces of code that I use to include styles and java-scripts on a settings page within the WordPress admin area. I have a class with a singleton that I use to initiate my admin pages. I stripped everything except the needed pieces of code to make it more readable.
The problem that I'm having is that by using the set-up below is that the style-sheets on the settings page are placed at the bottom of the page instead of in the head of the page. I can get it in the header by using other action hooks, but that would defeat the purpose. As far as I know the set-up I used is the same setup as is described with the wp_enqueue_style command.
There is a small hint with the command "wp_enqueue_style() can now be called mid-page (in the HTML body). This will load styles in the footer.". If that is true that would mean that the 'admin_print_scripts-*' hook is called somewhere mid-page instead of at the start en doing so places the css in the footer.
Any thoughts on that. an I doing something wrong ?
Thanks for your time.
This is how the singleton class is called within the functions.php file
theme::instance( );
This is part of the class that I used to create the admin pages
class theme {
static public function instance( )
{
is_null( self::$instance ) AND self::$instance = new self;
return self::$instance;
}
public function __construct()
{
add_action( 'admin_menu', array( $this, 'initMenu' ), 10, 0 );
add_action( 'admin_init', array( $this, 'registerAssets' ), 10, 0 );
}
public function registerAssets( )
{
// Styles
wp_register_style( 'cen', 'style.css', array( ), '1.0' );
wp_register_style( 'cen-settings', 'settings.css', array( 'cen' ), '1.0' );
// Scripts
wp_register_script( 'cen', 'settings.js', array( 'jquery' ), '1.0', true );
}
public function initMenu( )
{
// Index page
$index =add_menu_page( 'Cen', 'Cen', 'manage_options', 'cen-index', function (){ require_once( get_template_directory( ) . '/pages/index.php' ); }, get_template_directory_uri() . '/images/icons/logo_16.png', "110.00" );
// Settings page
$settings =add_submenu_page( 'cen-index', 'Cen - Settings', 'cen' ), 'Settings', 'manage_options', 'cen-settings', function (){ require_once( get_template_directory( ) . '/pages/settings.php' ); } );
// Add action for assets on the settings page
add_action( 'admin_print_scripts-' . $settings, array( $this, 'initSettingsPage' ));
}
public function initSettingsPage( )
{
// Styles used
wp_enqueue_style( 'cen' );
wp_enqueue_style( 'cen-settings' );
// Scripts used
wp_enqueue_script( 'jquery-ui-tabs' );
wp_enqueue_script( 'cen' );
}
}
The action hook admin_print_scripts you're using is used to add inline script so it's strongly recommended to use admin_enqueue_scripts to enqueue scripts/styles in the admin.
Try it. Hope it works!
Related
I need to have color picker settings filed in my plugin. I have registered a field and its saving value in the database correctly. But, in the admin area the picker user interface is not correct I think.
It should look like this:
https://ibb.co/7XRHqqL
But in my case it's looking like this:
https://ibb.co/vHvqmd0
Here is the code I have for registering the field
add_settings_field( 'iconBg', 'Background Color', array( $this, 'bg_settings_field' ), 'wpfyscroller-settings-page', 'wpfyscrollersection' );
register_setting( 'wpfyscrollerfields', 'iconBg', array('sanitize_callback'=>'sanitize_hex_color', 'default'=> '#000000') );
//Callback function
function bg_settings_field() { ?>
<input type="text" name="iconBg" value="<?php echo get_option('iconBg') ?>" class="cpa-color-picker" >
<?php }
Here is the code for enqueueing js
add_action('admin_enqueue_scripts', array( $this, 'enqueue_admin_js' ) );
function enqueue_admin_js() {
// Make sure to add the wp-color-picker dependecy to js file
wp_enqueue_script( 'cpa_custom_js', plugins_url( '/assets/js/colorPicker.js', __FILE__ ), array( 'wp-color-picker' ), '', true );
}
NOTE: My 'jquery' dependency already loaded with another script.
Here is the JS code:
(function ($) {$(function () {
// Add Color Picker to all inputs that have 'color-field' class
$(".cpa-color-picker").wpColorPicker();});})(jQuery);
Not sure what mistake I did, any help will be apricated.
Thanks
You can try the below code and hopefully work it. Your issue was on enqueue js.
/**
* Enqueue style & scripts for color picker
*
* #return void
*/
function enqueue_admin_js() {
// wp-color-picker
wp_enqueue_style( 'wp-color-picker' );
// Make sure to add the wp-color-picker dependecy to js file
wp_enqueue_script( 'cpa_custom_js', plugins_url( '/assets/js/colorPicker.js', __FILE__ ), array( 'wp-color-picker' ), '', true );
}
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_js' ) );
In previous when I develop WP shortcode then I load the CSS style depend on the shortcode params like this.
function test_shortcode( $atts ) {
$a = shortcode_atts( array(
'foo' => 'something',
), $atts );
echo "<style>";
.shortcode_unique_id {
//some css property depend on shortcode
}
echo "</style>";
}
But now it did not allow to add any style tag in the body otherwise it will show w3 validation error. We need to load style in the head tag.
Please anyone tell me how to load CSS style depend on shortcode params when calling the shortcode.
Advance Thanks
You can use wp_register_style and wp_enqueue_style to use style which is dependent on shortcode.
Main difference between wp_enqueue_* and respective wp_register_* functions, is that the first adds scripts/styles to the queue, the second prepares scripts/styles to be added.
The typical scenario of using both functions is when you want to register scripts/styles on theme init, and then enqueue them wherever necessary e.g.
add_action('init', 'my_register_styles');
function my_register_styles() {
wp_register_style( 'style1', get_template_directory_uri() . '/style1.css' );
wp_register_style( 'style2', get_template_directory_uri() . '/style2.css' );
wp_register_style( 'style3', get_template_directory_uri() . '/style3.css' );
}
/*This is you shortcode function*/
function test_shortcode( $atts ) {
$a = shortcode_atts( array(
'foo' => 'something',
), $atts );
wp_enqueue_style( 'style1' );
wp_enqueue_style( 'style2' );
wp_enqueue_style( 'style3' );
}
I'm trying to extend the default gallery widget in wordpress (v5.1.1) for a child theme. The widget shows up in the "Widgets" section of the dashboard, but the form fields never show up to edit the widget settings. Below shows the behavior with the default gallery widget, and then my widget (called "Extended Gallery").
What I did: I copied and pasted the content of /wp-includes/widgets/class-wp-widget-media-gallery.php into a file in my child theme called extended-gallery.php. The two files are the exact same except for at the beginning of extended-gallery.php where I changed the class name and handle.
see class-wp-widget-media-gallery.php
changes I made in extended-gallery.php:
class Extended_Gallery extends WP_Widget_Media {
/**
* Constructor.
*
* #since 4.9.0
*/
public function __construct() {
parent::__construct(
'media_gallery_extended',
__( 'Extended Gallery' ),
array(
'description' => __( 'Displays an image gallery.' ),
'mime_type' => 'image',
)
);
In functions.php, I register extended-gallery.php
<?php
//custom widgets
require_once("extended-gallery.php");
add_action("widgets_init", "custom_widgets_init");
function custom_widgets_init(){
register_widget("Extended_Gallery");
}
// add custom style
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles' );
function my_theme_enqueue_styles() {
$parent_style = 'parent-style';
wp_enqueue_style( $parent_style, get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-style',
get_stylesheet_directory_uri() . '/style.css',
array( $parent_style ),
wp_get_theme()->get('Version')
);
}
?>
How do I get the settings fields for my custom widget to work the same way as the default gallery widget? If I add additional fields, will it screw it up?
Your question is about creating a new plugin on wordpress.
You should 'register' your widgets. Like as following.
add_action( 'elementor/widgets/widgets_registered', [ $this, 'init_widgets' ] );
And you should activate your new plugin.
Good luck.
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.
The plugin I'm writng adds a custom url and handles it with a custom template using this:
public function url_for_calendar() {
add_rewrite_rule( 'calendario', 'index.php?upcoming-events=true', 'top' );
}
public function template_for_calendar( $path ) {
if ( get_query_var( 'upcoming-events' ) ) {
$template = get_template_directory() . '/upcoming-events.php';
return $template;
}
return $path;
}
public function upcoming_event_query_var( $vars ) {
$vars[] = 'upcoming-events';
return $vars;
}
add_action( 'init', array( $this, 'url_for_calendar' ) );
add_filter( 'template_include', array( $this, 'template_for_calendar' ) );
add_filter( 'query_vars', array( $this, 'upcoming_event_query_var' ) );
Things go as planned, but the problem I'm having is that on my header, where I have:
<body <?php body_class(); ?>>
body_class() ends up adding "home" to the list of classes. I read the docs for "is_home" and for "body_class", but I still don't understand why would it add the "home" class to this particular URL. Should I remove it (and add pertinent classes) with the body_class filter, or is there a better practice to accomplish this?
Using WP 4.1.
Actually, is_home() adds the class "blog".
The class "home" is added for the front page (is_front_page()).
If the settings are configured for a static front page and this code is run there, then you will get "home" as a body class.