In pure theory my question is whether it is possible to make one php function run twice taking a different variable each time and returning it as a result.
In practice, I'm tinkering with a child theme for WordPress (and learning some PHP basics). The original theme, twentysixteen, has a function to construct a link to Google fonts using several parameters and output the final URL, which is then taken by some other function and inserted in to the head template with added HTML markup - link, href, rel, type.
In my child theme I had to replace one of the default fonts completely, so instead of reconstructing the function, I simply minimized it to just contain and output the final font URL like so:
if ( ! function_exists( 'twentysixteen_fonts_url' ) ) :
function twentysixteen_fonts_url() {
$fonts_url = 'https://fonts.googleapis.com/css?family=Merriweather:400,700,900,400italic,700italic,900italic|Inconsolata&subset=latin,latin-ext,cyrillic,greek';
return $fonts_url;
}
endif;
What I'm trying to do now is get another URL (https://code.cdn.mozilla.net/fonts/fira.css) into this function to load a third font from Mozilla's CDN alongside the Google ones.
Can't put it into a separate function with a different name, because its output does not get picked up by the head template. Using an array puts both urls into one link href.
Can somebody please point me in the right direction?
Thank you.
Twentysixtee juste use one font, and the URL is generated with twentysixteen_fonts_url ()
If you look into Twentysixtee's function.php, twentysixteen_fonts_url () is use only 2 times. It's use to include font url in editor (line 144) and in front end (line 233).
Add an other font
If you want to add an other font you need to add it in your child theme.
You could do it by adding the following code in your function.php
function my_child_theme_font_url()
{
$fonts_url = 'https://code.cdn.mozilla.net/fonts/fira.css';
return $fonts_url;
}
function my_child_theme_enqueue_scripts()
{
wp_enqueue_style( 'my_child_font', my_child_theme_font_url(), array(), null );
}
add_action( 'wp_enqueue_scripts', 'my_child_theme_enqueue_scripts' );
As suggested by #MonkeyZeus the simplest way to achieve having another webfont enqueued in such cases is leaving the first function as it is and adding a different one right after it to enqueue the needed file like so:
add_action( 'wp_enqueue_scripts', 'register_custom_plugin_styles' );
function register_custom_plugin_styles() {
wp_register_style( 'fira', 'https://code.cdn.mozilla.net/fonts/fira.css' );
wp_enqueue_style( 'fira' );
}
As for the theoretical part of my question, I understand that somehow forcing a function to run a second time and produce a different output would not force the other function using this output to run a second time as well, producing a different result. For this to work, the calling function has to be modified, not the emitting one.
Thank you #MonkeyZeus and #Jordane-CURE for your help.
Related
I'm looking for a solution to conditionally load scripts and styles on specific Wordpress pages. I've searched for solutions, but have hit a dead end. I haven't been able to use php selectors, such as is_page(), in the functions.php file to do this. Here is an example of my past attempt:
function blog_style() {
if ( is_page('blog') ) {
wp_enqueue_style( 'blog' );
}
}
add_action( 'wp_print_styles', 'blog_style' );
I have a feeling this is because the functions.php file is loaded before the page has been identified. Any advice is helpful. I have a basic understanding of php and Wordpress codex. Thanks!
I understand your confusion in this matter and must confess that WordPress sometimes has strange ways to handle things.
First of all; you should enqueue scripts and styles in the wp_enqueue_scripts hook:
add_action('wp_enqueue_scripts', 'themeslug_styles');
function themeslug_styles() {
wp_enqueue_style(...);
}
Or in shorthand-/anonymous-function-format, if you prefer:
add_action('wp_enqueue_scripts', function () {
wp_enqueue_style(...);
});
The basic idea of your is_page('blog') in an if-statement is correct. But also check out this detailed info about conditional tags - maybe there are better ways to target the blog-page of your website (see "The Blog Page" on the linked resource).
You must use the if-statement inside your function, because it is only at the point of wp_enqueue_scripts, where the function is run, that WordPress has information about the actual content ready.
add_action('wp_enqueue_scripts', function () {
if (is_home()) {
wp_enqueue_style('themeslug-stylename', URL-to-your-style);
wp_enqueue_script('themeslug-scriptname', URL-to-your-script);
}
});
Addition: You are right, the functions.php file is mainly used to set everything up and connect functions as actions to WordPress hooks. Therefore, the code is executed quite early in the WordPress execution flow to give you access to as many hooks as possible. The downside is, as you experienced, that many things are not directly accessable at this point.
I think you are using the wrong hook here. Try
add_action( 'wp_enqueue_scripts', 'blog_style' );
You can check this function. I had used this function to dynamically load scripts on different post types and pages. I used the screen_id to specify the current page.
After digging internet for an answer I cannot find any idea about how to deal with my issue. I think the problem is common for someone who knows PHP a little bit.
To describe the situation. For some custom WordPress plugin I've got two PHP files: ff_config.php and loantest_form.php. First file contains some configurations of plugin plus following lines:
/**--------------------------TABLE SHORTCODES-----------------------*/
function render_loantest_form() {
include(plugin_dir_path(__FILE__) . 'front/loantest_form.php');
}
add_shortcode( 'render_loantest_form' , render_loantest_form );
/**--------------------------DISPLAY PLUGIN IN FOOTER-----------------------*/
add_action('wp_footer', 'display_loantest');
function display_loantest() {
echo render_loantest_form();
}
Which I suppose rendering second file containing enqueue scripts (js/css) and whole HTML output and placing in wp_footer where it exactly is on my page.
The question is: how to change mentioned lines to allow me to place render result (loantest_form.php) in specific div / id on page (for example #sidebar-slider)?
If you want to display your shortcode in a template file,
echo do_shortcode('[render_loantest_form]');
Enable the use of shortcodes in text widgets.
add_filter( 'widget_text', 'do_shortcode' );
And inside the text editor
[render_loantest_form]
You can read more about do_shortcode()
Note that you need to be sure that the file load in the render function is good and that it returns the expect content.
i want to hide few plugins style sheets to reduce load on our Index page and categories pages. Actually we want to display plugin style sheet only on Post not on other pages.
we have used following code in plugin, but it doesn't work. please help how to use it.
if( is_single() || is_singular('post') ) wp_enqueue_style('savrix-style.css');
If you are modifying your own plugin I see no reason your code wouldn't work. The is_single() condition is not needed, and will result in the stylesheet being loaded on custom post types and other singles that you don't intend.
However your wp_enqueue_style call is incomplete, so unless you have a wp_register_style call somewhere else defining the handle and URL of the stylesheet you need to change it to something along these lines:
if (is_singular('post')) {
wp_enqueue_style('savrix-style', plugins_url('savrix-style.css', __FILE__);
}
However, I get the impression that you are actually trying to remove a stylesheet included by a thirdparty plugin. It is generally a bad idea to modify a third-party plugin, as your modifications will be lost on the next update... it is very difficult to maintain that sort of modifications in the long run.
Instead make a new plugin and modify whatever you need from there.
What you want to achieve can be accomplished by:
Create a new folder in the wp-content/plugins folder, fx. my_load_reducer.
Inside that folder create a new file called my_load_reducer.php
Paste this in the file:
<?php
/*
Plugin Name: My Load Reducer
Description: Removes unneeded and unwanted stylesheets from other plugins
Version: 0.1
*/
//Use a class to avoid conflicts
class my_load_reducer {
function __construct() {
//Hook into wp_enqueue_scripts with a high priority
add_action( 'wp_enqueue_scripts', array($this, 'deregister_styles'), 1000 );
}
function deregister_styles() {
//Check that current post is not a single post
if (!is_singular('post')) {
//deregister the stylesheet - this removes the twentyfifteen
//main stylesheet - obviously you need to substitute the handle
//of the stylesheet you actually want to remove
wp_deregister_style( 'twentyfifteen-style' );
}
}
}
//Instantiate the class
$my_load_reducer = new my_load_reducer();
Activate the plugin through the wordpress admin.
You can remove perticular plugin css on selected page.
below code is remove plugin css to other pages and display only on post pages:
/*disable loading plugin css to page and load on post page*/
add_action('wp_print_styles', 'my_deregister_styles', 99999);
function my_deregister_styles()
{
if(!is_single())
{
wp_dequeue_style('plugin-css-handle');
wp_deregister_style('plugin-css-handle');
}
}
where 'plugin-css-handle' is perticular plugin's css handle which you want to remove.
wp_enqueue_script() as I read about so far and went through the source code instantiates new wp_scripts object 'representing' the script.
My question is how does wordpress know when to load the the script source when needed ?
For example, on index I need bootstrap and jquery, I enqueue bootstrap with jquery dependency in functions.php. How does wordpress know to automatically load the bootstrap on the first page ? What I want to understand is the logic behind it.
I have to create a new plugin and I need some scripts for a slideshow, what I want is to create a quality plugin, optimized using wp_enqueue_scripts, but I don't really understand the concept in-depth so I can use it properly (to load the scripts only when the plugin is activated)
You can treat wp_enqueue_scripts as a kind of action_hook. I.e. when it is time to create pages, it will include the file. You can also make it dependant on another file being loaded, so if jQuery is needed, you can stipulate this in the function and it will load after jQuery. This maintains seperation of your code.
If you want to optimize the code, you can make the function dependant on the page you are loading.
Forexample:
function prepare_scripts() {
if(is_front_page() )
wp_enqueue_scripts('myscript', 'path to script', array( 'jquery' ) );
}
add_action( 'wp_enqueue_scripts', 'prepare_scripts' );
As #knoblik suggests, you can set the priority for the add_action() if needed. This will probably enqueue the script in the order of the priority.
Using Wordpress you can add a hook to "the_content". In my code it looks like this.
add_filter("the_content", some_func);
So, in Wordpress every time there is a post "some_func" gets ran. So, let's say "some_func" looked like this.
function some_func( $content ) {
return $content . "<div id='my_div'></div>";
}
Using an ID attribute means there can only be one HTML element. What happens is, this function gets ran for every post there is in the database. That means if I had two posts then I have two divs with the ID "my_div" and if I have Javascript that relies on those IDs then the Javascript won't act correctly. Same for CSS.
So, what I need is a way to have this function ran once and no more than once. Anyone know of a way, maybe a wrapper, or a different filter I should be using?
I haven't tested this, but perhaps you can add this to the top of your some_func function:
remove_filter( 'the_content', 'some_func' );
In theory, it would call the filter once, and remove the filter after the first call.