I use a paid theme and unfortunately it does not offer the possibility to use own icons from a font. Since I have to observe the GDPR and cannot use Google icons, I would like to use local icons. The only possibility is to import my own CSS file and define the unicodes of the icons.
I already use a child theme and have already successfully defined my local icon font in the parent theme, but I am not sure how to transfer my customisations to the child theme.
Parent: /themes/mytheme/includes/assets.php
I have not made any changes here. I just added the css definition of my font to the existing icons.css. But the goal would be to separate this. So here I have to add another line in the register_scripts function so that my CSS is loaded.
wp_register_style( 'local-icons', c27()->template_uri( 'assets/dist/local-icons'.$suffix.'.css' ), [], \MyTheme\get_assets_version() );
class Assets {
...
...
public function register_scripts() {
...
...
...
wp_register_style( 'mytheme-icons', c27()->template_uri( 'assets/dist/icons'.$suffix.'.css' ), [], \MyTheme\get_assets_version() );
...
...
}
}
...
public function enqueue_scripts() {
global $wp_query;
...
...
wp_enqueue_style( 'mytheme-icons' );
...
}
What is c27?
function c27() {
return mytheme()->helpers();
}
Parent: /themes/mytheme/includes/src/admin/admin.php
*Here I have added the following to the enqueue_scripts() function:
wp_enqueue_style( 'mytheme-local-icons' );
In the function get_icon_packs() in the return of wp_send_json I added the following:
'local-icons' => array_values( \MyTheme\Utils\Icons\Local_Icons::get() ),*
class Admin {
...
...
public function enqueue_scripts() {
...
...
wp_enqueue_style( 'mytheme-icons' );
...
}
...
...
public function get_icon_packs() {
if ( ! is_user_logged_in() ) {
return;
}
return wp_send_json( [
'mytheme-icons' => array_values( \MyTheme\Utils\Icons\mytheme_Icons::get() ),
'font-awesome' => array_values( \MyTheme\Utils\Icons\Font_Awesome::get() ),
] );
}
....
....
}
Parent: /themes/mytheme/includes/utils/icons/theme-icons.php
Here I created a new file and did the mapping for my font.
<?php
namespace MyTheme\Utils\Icons;
if ( ! defined('ABSPATH') ) {
exit;
}
class Theme_Icons {
public static function get() {
return [
'' => 'icon-add-circle-1',
'' => 'icon-airplane',
'' => 'icon-alien',
...
...
];
}
}
I have made my changes in each of the above files and everything was working as expected. But will be cause a problem when an update of the theme will be installed in future. How can I extend the classes in the child theme so that I can use my own local icons?
Hope there is somebody out there who can help me a bit.
PS: I'm not a developer, but understand a bit of programming
Create a child theme and add your file custom-icons.css
Then add following code to your file functions.php
add_action('wp_enqueue_scripts', 'enqueue_custom_icons', 20);
function enqueue_custom_icons(){
wp_enqueue_style('custom-icons', get_stylesheet_directory_uri() . '/custom-icons.css', [], '1.0.0');
}
This will properly add your CSS file to your theme. And having a child theme allows you to update the parent theme (main theme) without having to re-add this code upon update.
Related
I'm trying to create a plugin for shortcodes. But my activation hook is not working. Plugin is activated in my wp-admin/plugins page but nothing works which is in my code like:
My enqueue & shortcode functions are not working. I've tried plugin_dir_path(__FILE__) & plugin_dir_url(__FILE__) b ut nothing works.
Here is my code:
if (!class_exists( 'DiliviBlocks' )) {
class DiliviBlocks {
public function __construct() {
$this->setup_actions();
$this->plugin_dir = plugin_dir_path(__FILE__);
}
/**
* Setting up Hooks
*/
public function setup_actions() {
register_activation_hook( plugin_dir_path(__FILE__), array( $this, 'activate_plugin' ) );
}
/**
* Activate callback
*/
public function activate_plugin() {
add_action( 'wp_enqueue_scripts', array($this, 'dilivi_blocks_scripts') );
add_shortcode( 'vans_search_form', array($this, 'vans_search_form_shortcode') );
}
public function dilivi_blocks_scripts() {
wp_enqueue_style( 'dilivi-blocks-plugin-css', plugin_dir_path(__FILE__) . '/assets/css/styles.css');
wp_enqueue_script( 'dilivi-blocks-plugin-jquery', plugin_dir_path(__FILE__) . '/assets/js/jquery.js' );
wp_enqueue_script( 'dilivi-blocks-plugin-js', plugin_dir_path(__FILE__) . '/assets/js/scripts.js' );
}
public function vans_search_form_shortcode($atts) {
return 'Hello World';
}
}
$diliviBlocks = new DiliviBlocks();
}
Please help me. I'm stuck
The documentation states that you only need the plugin directory name, and the name of the initial file. You should not include the whole path to it.
If your plugin contains only the file, than just __FILE__ would suffice.
In your case, it will probably be something like dilivi-blocks/divili-blocks.php.
Also, be aware that functions will only be executed once -- when your plugin is activated. If it is already active, the functions will not execute.
You should know that enqueueing stylesheets and the like will have to be done every time a page loads, so binding them to a single-use hook will not work. The wp_enqueue_scripts hook should be used for that.
I am working on a way to disable a specific plugin on a certain product page. I've cobbled this together from things I found online and the plugins code itself but its not working. Curious to have some fresh eyes have a look and let me know what might be failing. The post id of the product is 2679320. The actions I have set to remove are the ones referenced in the plugin wp_enqueue_scripts. Here is the code I'm trying by loading to snippets:
function remove__construct() {
global $post;
$ids = array(2679320);
if(in_array($post->ID,$ids)):
remove_action(‘wp_enqueue_scripts’,array($this,’enqueue_scripts’));
remove_action(‘plugins_loaded’,array($this,’load_txt_domain’),99);
remove_action(‘wp_footer’,array($this,’get_popup_markup’));
remove_filter( ‘pre_option_woocommerce_cart_redirect_after_add’, array($this,’prevent_cart_redirect’),10,1);
endif;
}
add_action(‘wp_head’, ‘remove__construct’, 1);
Any ideas why this isn't working? What did I miss? Anyone have better way to do this?
You can use Plugin Organizer. It allows you to selectively disable a plugin on a page or a complete post type.
There are 2 ways to disable plugin.
The first way is to create a custom plugin that removes the action that used to initialize your target plugin. The second way is to remove actions and filters which add scripts, styles and makes changes on a page.
Either way you choose, you have to remove actions after they've been added and before they actually worked. That means that for the first way in most cases you have to use plugins_loaded hook which can't be used in your functions.php (the first hook which can be used in functions.php is load_textdomain hook). in case you want to disable the plugin on certain pages you have to somehow get the current post ID, which isn't so easy because global $post variable is not available yet (The earliest hook with $post is wp).
Parameters for your remove_action depend on plugin add_action. The main point here is that all parameters of your remove_action must be the same as add_action parameters. Here are some examples :
add_action('plugins_loaded', 'init_function_name');
remove_action('plugins_loaded', 'init_function_name');
add_action('plugins_loaded', 'init_function_name', 100);
remove_action('plugins_loaded', 'init_function_name', 100);
class Plugin_Classname {
public static function init() {
add_action( 'plugins_loaded', array( __CLASS__, 'on_init' ) );
}
}
remove_action( 'plugins_loaded', array( 'Plugin_Classname', 'on_init' ) );
class Plugin_Classname {
public function __construct(){
add_action('plugins_loaded', array($this, 'init'), 99);
}
public static function get_instance(){
if(self::$instance === null){
self::$instance = new self();
}
return self::$instance;
}
}
remove_action('plugins_loaded', array( Plugin_Classname::get_instance() , 'init'), 99);
Let's begin with the easiest way. Assume that removing scripts and styles is enough. Then you have to find wp_enqueue_scripts hooks in the plugin source. Eq.:
class Xoo_CP_Public{
protected static $instance = null;
public function __construct(){
add_action('plugins_loaded',array($this,'load_txt_domain'),99);
add_action('wp_enqueue_scripts',array($this,'enqueue_scripts'));
add_action('wp_footer',array($this,'get_popup_markup'));
add_filter( 'pre_option_woocommerce_cart_redirect_after_add', array($this,'prevent_cart_redirect'),10,1);
}
public static function get_instance(){
if(self::$instance === null){
self::$instance = new self();
}
return self::$instance;
}
}
As we need global $post variable we gonna use wp hook. Place the code below in functions.php:
function disable_plugin() {
global $post;
$ids = array( 2679320 ); // Disable plugin at page with ID = 2679320
if( in_array( $post->ID ,$ids ) ) {
remove_action('wp_enqueue_scripts',array( Xoo_CP_Public::get_instance(),'enqueue_scripts'));
remove_action('plugins_loaded',array(Xoo_CP_Public::get_instance(),'load_txt_domain'),99);
remove_action('wp_footer',array(Xoo_CP_Public::get_instance(),'get_popup_markup'));
remove_filter( 'pre_option_woocommerce_cart_redirect_after_add', array(Xoo_CP_Public::get_instance(),'prevent_cart_redirect'),10,1);
}
}
add_action( 'wp', 'disable_plugin' );
What if we want to remove an action is used to initialize this plugin? Let's take a look at add_action:
add_action('plugins_loaded','xoo_cp_rock_the_world');
In this case we can't use plugins_loaded hook because add_action is being called without priority parameter. If it's being called with priority parameter we could just create disable-plugin.php file in /wp-content/plugins folder and place this code there:
function disable_plugin() {
remove_action('plugins_loaded', 'xoo_cp_rock_the_world', 100);
}
add_action('plugins_loaded','disable_plugin');
But it's useless in this case without priority parameter. Yet we can cheat! We don't have to use any hooks and call remove_action directly. We should call it after target plugin add_action was called. Plugins are loaded in alphabetical order so if we named our plugin 'zzz-disable-plugin.php` with this lines of code:
/* Plugin Name: zzz-disable-plugin */
remove_action('plugins_loaded', 'xoo_cp_rock_the_world');
The target plugin will be disabled. At all pages though. I haven't find a way to get ID of current page on such an early hook. But we can use URI :
/* Plugin Name: zzz-disable-plugin */
if( 'product/polo' == trim( $_SERVER[ 'REQUEST_URI' ], '/' ) ) {
remove_action('plugins_loaded', 'xoo_cp_rock_the_world');
}
I'm currently using Foobox lightbox (free) plugin, and apparently the plugins' files are loaded on every page regardless of whether it's used or not. However I would like to change this, but I can't seem to find any handles to dequeue the scripts through.
It seems that the scripts are called by the code beneath, which to me at least, doesn't show any handles. I've tried using remove_action(...) to "counter" them as well as various inputs in wp_dequeue_script() to try and target the files directly - e.g. wp_dequeue_script('foobox.free.min.js')
class Foobox_Free extends Foo_Plugin_Base_v2_1 {
const JS = 'foobox.free.min.js';
const CSS = 'foobox.free.min.css';
const CSS_NOIE7 = 'foobox.noie7.min.css';
const FOOBOX_URL = 'http://fooplugins.com/plugins/foobox/?utm_source=fooboxfreeplugin&utm_medium=fooboxfreeprolink&utm_campaign=foobox_free_pro_tab';
const BECOME_AFFILIATE_URL = 'http://fooplugins.com/affiliate-program/';
private static $instance;
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Foobox_Free ) ) {
self::$instance = new Foobox_Free();
}
return self::$instance;
}
/**
* Initialize the plugin by setting localization, filters, and administration functions.
*/
private function __construct() {
//init FooPluginBase
$this->init( FOOBOXFREE_FILE, FOOBOXFREE_SLUG, FOOBOX_BASE_VERSION, 'FooBox FREE' );
if (is_admin()) {
add_action('admin_head', array($this, 'admin_inline_content'));
add_action('foobox-free-settings_custom_type_render', array($this, 'custom_admin_settings_render'));
new FooBox_Free_Settings();
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_GETTING_STARTED, array( $this, 'render_page_getting_started' ) );
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_SETTINGS, array( $this, 'render_page_settings' ) );
add_action( 'admin_notices', array( $this, 'admin_notice_foogallery_lightboxes' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_ignore_notice', array( $this, 'admin_notice_foogallery_lightboxes_ignore' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_update', array( $this, 'admin_notice_foogallery_lightboxes_update' ) );
add_action( 'admin_print_scripts', array( $this, 'admin_notice_foogallery_lightboxes_inline_js' ), 999 );
add_filter( 'foobox-free-has_settings_page', '__return_false' );
} else {
// Render JS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
add_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
// Render CSS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
if ( $this->is_option_checked('disable_others') ) {
add_action('wp_footer', array($this, 'disable_other_lightboxes'), 200);
}
}
}
How, if possible, do I dequeue these scripts (and styles) without editing the plugin file directly?
Edit
Below I've added the things I've tried doing to remove the scripts (all added to functions.php):
add_action( 'wp_enqueue_scripts', 'remove_foobox_scripts', 100 );
function remove_foobox_scripts() {
if ( !is_page('my-page') ) {
wp_deregister_script( 'foobox.free.min.js' );
wp_dequeue_script( 'foobox.free.min.js' );
}
}
Also tried the below, which is just a straight copy from the foobox file:
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
remove_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
Also tried the below, where the array( part is removed:
remove_action('wp_enqueue_scripts','frontend_print_scripts', 20);
remove_action('foobox-free_inline_scripts', 'inline_dynamic_js');
remove_action('wp_enqueue_scripts', 'frontend_print_styles');
The problem with the way you are trying to do this stems from the order in which things happen in Wordpress.
You are relying on the conditional tags like is_page('my-page') to determine whether or not to load the plugin. These conditional tags do not become available until Wordpress has parsed the URL for the current query, and at this point all the plugins and your theme have already been loaded. Even if you parse the URL yourself instead of using the conditional tags you cannot be sure your code will run before the plugins are loaded.
The solution is to add your code as an mu-plugin. These are loaded before normal plugins so you can use an option (option name) filter here to alter the plugins you want to be loaded.
Option filters pass an array to your function containing the values which are set for that option, so in this case you want to hook option_active_plugins.
You can find the values to use for by running print_r(get_option('active_plugins')); or look through the plugins folder of your wordpress install.
The following example is specific to your question, but you could modify it to make a more comprehensive set of rules, adding and removing multiple plugins on different pages based on many conditions.
My function checks you are not in wp-admin and then has 2 conditions. The first disables a normally active plugin on the specified pages, the second enables a normally disabled plugin on the specified pages.
<?php
add_filter( 'option_active_plugins', 'add_or_remove_plugins' );
function add_or_remove_plugins( $plugins ) {
if (strpos( $_SERVER['REQUEST_URI'], '/wp-admin/' ) !== 0) { // Disable in admin pages or admin plugin settings stop working properly
if (strpos( $_SERVER['REQUEST_URI'], '/remove-plugin-here/' ) === 0) { // Conditonal tags still unavailable so you have to parse urls yourself
$k = array_search( 'foobox-image-lightbox/foobox-free.php', $plugins ); // This will stop an active plugin from loading
if( false !== $k ){
unset( $plugins[$k] );
}
}
if (strpos( $_SERVER['REQUEST_URI'], '/add-plugin-here/' ) === 0) {
$plugins[] = 'foobox-image-lightbox/foobox-free.php'; // This will load the plugin along with all the active plugins
}
}
return $plugins;
}
?>
To install just change the values to suit, paste into a file and upload into your mu-plugins folder
EDIT
Looks like your inline js is added to wp_head during the constructor of the Foobox_Free class. You could try adding this to your functions.php:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
$foo = Foobox_Free::getInstance();
remove_action('wp_head', array($foo, 'inline_dynamic_js'));
}
or if that doesn't work then maybe this:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
remove_action('wp_head', array('Foobox_Free', 'inline_dynamic_js'));
}
The action is added inside a private function, so I don't know if either of those will actually work. Give it a shot. If not my first answer will as it stops the plugin from loading at all on the specified pages.
UPDATE
Well, I was close... Here's the code to remove the scripts, as supplied by the plugin author.
$foobox = Foobox_Free::get_instance();
remove_action('foobox-free_inline_scripts', array($foobox, 'inline_dynamic_js'));
I'm trying to develop my first Wordpress plugin and I got staled in the very first stage. I'm trying to setup some options and database tables when the plugin is activated, but no luck. No matter what I do, the plugin activates, but the database is untouched and the options are not stored in DB. I tried echoing inside the constructor, but it seems that it never reaches it. I have debug activated in WP, but no error is being reported. The function is not being hooked. Does someone can spot what's wrong with my code?
Thanks for any help in advance.
class Myplugin {
private static $instance;
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
register_activation_hook( __FILE__, array( &$this, 'plugin_activate' ) );
}
public function plugin_activate() {
if ( version_compare( get_bloginfo( 'version' ), '3.8.2', ' < ' ) ) {
deactivate_plugins( basename( __FILE__ ) );
} else {
$rlm_rsvplus_options = array(
'db_version' => '1.0',
'event_name' => '',
'end_date' => '',
);
update_option( 'rlm_myplugin_options', $rlm_myplugin_options );
require_once( "includes/rlm_myplugin_db_setup.php" );//It never reaches this file.
}
}
}
$myplugin = Myplugin::get_instance();
Back to the WordPress documentation.
<?php register_activation_hook( $file, $function ); ?>
Parameters
$file
(string) (required) Path to the main plugin file inside the wp-content/plugins directory. A full path will work.
Default: None
$function
(callback) (required) The function to be run when the plugin is activated. Any of PHP's callback pseudo-types will work.
Default: None
Possible issue
If calling a function from a file that is outside of main plugin file, then the hook will not work as it is not pointing to the right file. FILE will point to the file where the code is written. So if you happen to include this part of code from elsewhere (another file - not the main plugin file) it's not supposed to work unless you point the right path.
Solution
A solution could be declaring a constant in the main plugin file.
your_main_plugin_file.php
define(PLUGIN_FILE_URL, __FILE__);
and then use it in your included file like so.
includes/some_file.php
<?php register_activation_hook( PLUGIN_FILE_URL, ['your_class_name_here', 'your_class_method_name_here']); ?>
or if you use functions instead of classes then do
<?php register_activation_hook( PLUGIN_FILE_URL, 'your_function_name_here'); ?>
The register_activation_hook call needs to be outside of the class itself.
Something like:
class Myplugin {
private static $instance;
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
// do other stuff here
}
public function plugin_activate() {
if ( version_compare( get_bloginfo( 'version' ), '3.8.2', ' < ' ) ) {
deactivate_plugins( basename( __FILE__ ) );
} else {
$rlm_rsvplus_options = array(
'db_version' => '1.0',
'event_name' => '',
'end_date' => '',
);
update_option( 'rlm_myplugin_options', $rlm_myplugin_options );
require_once( "includes/rlm_myplugin_db_setup.php" );
}
}
register_activation_hook( __FILE__, array( 'Myplugin', 'plugin_activate' ) );
You can read more on the following tutorial by Francis Yaconiello about How to write WordPress plugin.
In order to work register_activation_hook OR register_deactivation_hook the functions should be in index file OR we need to specify the full path to the file argument.
Replace this:
register_activation_hook( FILE, array( &$this, 'plugin_activate' ) );
With:
register_activation_hook( FILE . 'plugin-main-file.php', array( &$this, 'plugin_activate' ) );
Here the point is register_activation_hook( $file, $function );
Here $file means Path to the main plugin file
Reference: https://codex.wordpress.org/Function_Reference/register_activation_hook
Thanks,
- Adi
How to get following to work properly in Wordress Theme functions.php file?
I haven't figured out how to make the top function available to the bottom function within the theme's functions.php file. I'm not grasping how to setup hooks so they can work together. Thank you.
Filter/helper/whateveryoucallit function:
function poohToPee( $pooh_log )
{
switch( $pooh_log )
{
case 'gross-poop':
$pee_equivalent = 'Grossest of Pees';
break;
case 'ok-poop':
$pee_equivalent = 'Bland Snack Pee';
break;
case 'shang-tsung-plop':
$pee-equivalent = 'Random U-Stream';
break;
}
return $pee_equivalent;
}
Ajax handler function:
function screw_loose()
{
if( isset($_REQUEST['pooh_log']) )
{
echo poohToPee( $_REQUEST['pooh_log'] );
}
}
add_action('wp_ajax_priv_screw_loose', 'screw_loose')
The add_action usually calls the function you are passing through at the point that hook is called.
Since you are using some sort of ajax hook are you really able to make sure your function isn't being called? It wouldn't be echo-ing anything out to the screen since it is running in the background.
Normally any function you define in functions.php is readily available to use within the theme.
It is obviously normally best to organize and have classes, in which case you'd pass the method to the hook as an array, for example add_action( 'admin_init', array( $this, 'someFunction' ) ); and that add_action I just did would be put in the __construct function of the class.
For instance you could do this:
class helloWorld
{
function __construct()
{
add_action( 'admin_init', array( $this, 'echoItOut' ) );
}
function echoItOut()
{
echo 'Hello World';
}
}
$helloWorld = new helloWorld;
Alternatively you could also do this:
class helloWorld
{
function echoItOut()
{
echo 'Hello World';
}
}
$helloWorld = new helloWorld;
add_action( 'admin_init', array( $helloWorld, 'echoItOut' ) );
Or simply:
function echoItOut()
{
echo 'Hello World';
}
add_action( 'admin_init', 'echoItOut' );
If you put any of these blocks of code I provided in your functions.php file and go to your Dashboard you will see 'Hello World' printed out at the top under the admin bar most likely (might vary from theme to theme if the dashboard has custom styling).