1

I'm creating a plugin to add a custom post type. For every custom post type, I also create custom single template. The custom single template is not using get_header(); or wp_head() functions, it is coded from scratch manually. I've enqueued the style like this:

<link rel="stylesheet" href="<?php echo esc_url( plugins_url( '/public/css/wp-myplugin-public.min.css', dirname(__FILE__) ) ); "/>

And when I submitted the plugin, the WordPress team encouraged me to use built-in WordPress function such as wp_enqueue_style() instead of above method.

Since I don't use get_header() and wp_head, there's no way it can be enqueued into the header of my single template.

I've tried several ways like this:

function wp_myplugin_enqueue_style() {
global $post;
if ($post->post_type == 'myplugin') {
       wp_enqueue_style( 'myplugin-public-css',  plugin_dir_url( __FILE__ ) . ' public/css/wp-myplugin-public.min.css ' );
}
}
add_action( 'wp_enqueue_scripts', ' wp_myplugin_enqueue_style' );

Including like this:

function wp_myplugin_enqueue_style() {
if ( get_post_type( get_the_ID() ) == 'myplugin' ) {
       wp_enqueue_style( 'myplugin-public-css',  plugin_dir_url( __FILE__ ) . ' public/css/wp-myplugin-public.min.css ' );
}
}
add_action( 'wp_enqueue_scripts', ' wp_myplugin_enqueue_style ' );

Also like this:

function wp_myplugin_enqueue_main_css() {
    if (is_page_template('wp-myplugin-base-template.php')){
    wp_enqueue_style( 'myplugin-public-css',  plugin_dir_url( __FILE__ ) . ' public/css/wp-myplugin-public.min.css ' );
    }
}
add_action( 'wp_enqueue_scripts', 'wp_myplugin_enqueue_main_css' );

The above codes didn't work at all.

The <head> of the single template looks like this:

<?php
** Custom Single Template for MyPlugin
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
    <head>
<?php if (in_array('wordpress-seo/wp-seo.php' || 'wordpress-seo-premium/wp-seo-premium.php', apply_filters( 'active_plugins', get_option('active_plugins' )))) :
    if ($meta_title = get_post_meta($post->ID, '_yoast_wpseo_title', true ));
    elseif ($meta_title = get_post_meta( get_the_ID(), myplugin_prefix( 'meta-title' ), true ));
    else $meta_title = get_option(sanitize_text_field('myplugin_meta_title'));
    if ($meta_description = get_post_meta($post->ID, '_yoast_wpseo_metadesc', true ));
    elseif ($meta_description = get_post_meta( get_the_ID(), myplugin_prefix( 'meta-description' ), true ));
    else $meta_description = get_option(sanitize_text_field('myplugin_meta_description'));
?>
<?php
if ($set_noindex = get_post_meta( get_the_ID(), myplugin_prefix( 'noindex' ), true ));
else $set_noindex = get_option(sanitize_text_field('wp_myplugin_noindex'));
if ($set_nofollow = get_post_meta( get_the_ID(), myplugin_prefix( 'nofollow' ), true ));
else $set_nofollow = get_option(sanitize_text_field('wp_myplugin_nofollow'));
?>
<?php
if ($set_noindex === "yes") {
$noindex = "noindex";
} else {
$noindex = "index";
}
if ($set_nofollow === "yes") {
$nofollow = "nofollow";
} else {
$nofollow = "follow";
}
?>
        <meta charset="<?php bloginfo( 'charset' ); ?>">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="profile" href="http://gmpg.org/xfn/11">
        <link rel="pingback" href="<?php echo esc_url( get_bloginfo( 'pingback_url' ) ); ?>">
        <link rel="icon" type="image/png" href="<?php echo esc_html(get_option('myplugin_upload_favicon')); ?>">
        <title><?php echo $meta_title; ?></title>
        <meta name="description" content="<?php echo $meta_description; ?>">
        <meta name="robots" content="<?php echo $noindex ?>, <?php echo $nofollow ?>" />
        <meta name="googlebot" content="<?php echo $noindex ?>, <?php echo $nofollow ?>, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
        <meta name="bingbot" content="<?php echo $noindex ?>, <?php echo $nofollow ?>, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
        <!-- WordPress team doesn't allow below method to enqueue the style -->
        <link rel="stylesheet" href="<?php echo esc_url( plugins_url( '/css/wp-myplugin-public.min.css', dirname(__FILE__) ) ); ?>"/>
<?php endif; ?>
<?php $custom_css = get_option(sanitize_text_field('wp_myplugin_custom_css'));
if ($custom_css == '') {
    echo '';
} else {
    echo '<style type="text/css">'.$custom_css .'</style>';
  }
?>
    </head>

In order to include the wp-myplugin-public.min.css stylesheet, what is the best method I can use? I really need your help on this.

Thank you very much in advance!

2 Answers 2

1

First, you've got a heck of an obvious coding error in every one of your wp_enqueue_style calls: you have spaces in your quotations. Furthermore, because you are choosing not to call the wp_head() method, the hook of the same name will not be called. That hook, in turn, calls the wp_enqueue_scripts method, which calls the hook of the same name. As you're not doing any of this, your attempts to use the wp_enqueue_scripts hook won't work. (You'd have to trace the code like I did to know this.) So, there are two reasons why you are FUBAR.

A word on wp_head(): it is used by the WordPress core to do a whole crap ton of things so WordPress can operate properly. It is good practice to use it so WordPress doesn't break, and it is a basic concept of WP development. If you don't use the built-in WP core, you'll continue to encounter these errors and you will have to figure out how to do the required core functions of the WP process on your own (which will definitely season you). 5 second read to learn where to call wp_head(). Spoiler alert: it's in between the <head> tags.

With all that in mind, here is a solution of stylesheet output only. Modify your template to tell WordPress to output a specific style sheet, then tell it where to output it (as you are choosing not to make the call to wp_print_styles() to output everything else that may be required). This can be done by getting a global instance of an class known as WP_Styles, and "doing" that single item. (Alternatively, and preferably, use wp_head() in place of the wp_styles()... line.)

<?php
** Custom Single Template for MyPlugin
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
    <head>
    <?php
    // Here's where the magic happens
    wp_enqueue_style('myplugin-public-css');        // Tell WP to output this
    wp_styles()->do_item('myplugin-public-css');    // Do the output
    ?>
    ...

Next, you have to tell that WP_Styles instance what that myplugin-public-css is. This is where enqueuing comes into play. The wp_enqueue_style() method loads up the object we will later grab in the above template. As you're not using wp_head(), you'll have to hook into something else. So, let's try the init hook ...

// Notice there are no spaces inside the quotation marks ...
// We use register the script so it is not output unless we enqueue it later.  That saves on resources.
function wp_myplugin_register_style() {
    wp_register_style( 'myplugin-public-css', plugin_dir_url(__FILE__).'public/css/wp-myplugin-public.min.css' );
}
add_action( 'init', 'wp_myplugin_register_style' );

That should about do it. And, here's a protip: put wherever you make the call for your template. That way, your stylesheet is registered sitting in wait until such a time that it is needed: and it is only needed when it is enqueued alongside the calling of your template.

On another note, you said you don't use get_header(), but I see it plain as day in your code. No need to respond one way or another on this, just wanted to point it out as no one likes to violate their own coding policy!

4
  • 1
    Wow thank you very much for your detailed answer. I never knew that wp_styles() exists until now. It now works perfectly! Thank you SO MUCH!! Also, yeah I noticed that there are spaces in the quotations, it's because I edited them on the fly while posting this question. Your answer deepens my knowledge about some other built-in instances I can use. Thank you!
    – Walter P.
    May 29, 2020 at 10:39
  • Sure. If that is all, please upvote my answer and set it as the accepted answer. Also, I'd like to advise that you review the WordPress Themes Handbook for further questions you may have regarding your templates.
    – Mort 1305
    May 29, 2020 at 13:33
  • 1
    Yes that's all. I've voted your answer but since I have less than 15 reputation, it doesn't appear (StackXchange doesn't show it). Yes thanks very much for it. Works perfectly now!
    – Walter P.
    May 30, 2020 at 14:40
  • You betcha. And, thank you.
    – Mort 1305
    May 31, 2020 at 1:18
-1

You can create your own hook using do_action( 'your_hook_name' );

In your cpt template file:

<head>
...
<?php do_action( 'your_hook_name' ); ?>
...
</head>

Then add a callback to the hook:

function add_css_file() {
   ?><link rel="stylesheet" href="<?php echo esc_url( plugins_url( '/public/css/wp-myplugin-public.min.css', dirname(__FILE__) ) ); "/><?php
}
add_action( 'your_hook_name', 'add_css_file' );
4
  • In his code, he points out that "WordPress team doesn't allow below method to enqueue style", which is the <link> methods you propose. (Please refer to his code a dozen lines from the end just above the call to get_header().)
    – Mort 1305
    May 29, 2020 at 5:49
  • Yes, but he doesn't want to use get_header().
    – Mort 1305
    May 29, 2020 at 13:34
  • Hello @tommy, thank you. It'd work great if I use get_header() or wp_head() function. Makasih anyway :D
    – Walter P.
    Jun 2, 2020 at 4:32
  • Yeah, you're welcome... sama sama. Jun 3, 2020 at 5:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.