Support » Plugins » Hacks » Best way to create a css file dynamically

  • Resolved victor_jonsson

    (@victor_jonsson)


    Hi there!

    What would be the best way to dynamically generate a stylesheet in a theme? I can think of three different solutions:

    1) Having a separate file in theme and assume where the file wp-load.php is located and include it like ‘/../../wp-load.php’.

    2) In the file functions.php check if a certain variable is set and if so generate the stylesheet and terminate the script.

    3) Register an ajax function and link to the url of the ajax function (not sure if wordpress checks if AJAX-requests is sent with correct request headers).

    Is there any other way to accomplish this? I know that the first solution is most straight forward but I consider it to be something of a hack, especially if it exists a “correct” way of doing it.

    / vic

Viewing 15 replies - 1 through 15 (of 21 total)
  • esmi

    (@esmi)

    Forum Moderator

    1. Assuming this file is .css, you’d ideally enqueue it and let WordPress handle the loading.

    2. Why not just add the .css to the head of the page – again by enqueueing it?

    Sorry. I wasn’t to clear about that. The stylesheet is generated on the fly, so it will have the extension .php. I could of course generate it and save it to a static file but that would actually become more complex in my case.

    esmi

    (@esmi)

    Forum Moderator

    Have you had a look at http://css-tricks.com/css-variables-with-php/ There’s a couple of ways to use a css file with a .php extension. So you could generate the file on the fly and enqueue it using wp_enqueue_style. At worst, you’d end up enqueuing an empty file but, if you also bundled this in with a variable/flag, you could enqueue it only if it contains something. Either way, it should be possible to do the whole thing via the theme’s functions.php file.

    Sorry again, I guess my question still is to fuzzy 🙂

    I’m not asking how to dynamically generate a css file. My question is how to load wordpress from within the file that generates the CSS. (I guess my examples makes more sense now that I have explained that).

    Edit: I now realize how bad the title of this post is 🙂

    esmi

    (@esmi)

    Forum Moderator

    Sorry? You want to load that CSS file into WordPress?

    1) I have a CSS-file that generates a piece of CSS code
    2) I enqueue the CSS file (that has .php as extension) in functions.php

    For example:

    function.php

    wp_enqueue_stylesheet('my-dynamic-css', get_stylesheet_directory_uri().'my-css.php');

    my-css.php

    <?php
    header('Content-type: text/css');
    
    require '/../../../wp-load.php'; // load wordpress bootstrap, this is what I don't like
    
    // and from here on generate the css file and having access to the
    // functions provided by wordpress

    So my questions is if it exists any alternative way to bootstrap wordpress. A way where you don’t assume that you have knowledge about where the file wp-load.php is located?

    esmi

    (@esmi)

    Forum Moderator

    I don’t understand why you’re calling wp-load.php in the first place. Can you elaborate on why?

    Because the administrator of the website gets the possibility to configure a bunch of stuff in wp-admin that’s in regard to theme. The code could look something like:

    <?php
    header('Content-type: text/css');
    require '/../../../wp-load.php'; // load wordpress bootstrap, this is what I don't like
    $css_options = get_option('website_css');
    ?>
    body {
      background: <?php echo $css_options['background'] ?>;
    }
    esmi

    (@esmi)

    Forum Moderator

    Because the administrator of the website gets the possibility to configure a bunch of stuff in wp-admin that’s in regard to theme.

    That still wouldn’t need to you call wp-load.php, though. I’ve done similar themes and simply enqueued the custom CSS and let WP handle the rest.

    How could that be possible? We must be talking about different things here. How do I get WordPress to know which CSS rules to put in the generated CSS? How do I make wordpress to dynamically generate a CSS from options added by the administrator in wp-admin? Could you please give me a code example?

    esmi

    (@esmi)

    Forum Moderator

    How do I get WordPress to know which CSS rules to put in the generated CSS?

    Via basic conditional statements. if..endif or switch statements. for example:

    // Output option-based style
    if( !function_exists( 'emporium_style') ) :
    function emporium_style() {
    	global $emporium_options;
    
    	// Slider controls
    	if( isset( $emporium_options['display_slider_controls'] ) && $emporium_options['display_slider_controls'] == 'no' ) :?>
    	<style type = "text/css">
    	.eslideshow .auto_controls,.eslideshow .prev, .eslideshow .next {display:none;}
    	</style>
    	<?php endif;
    
    	// eShop panels product title
    	if( isset( $emporium_options['display_eshoppanel_legend'] ) && $emporium_options['display_eshoppanel_legend'] == 'no' ) :?>
    	<style type = "text/css">
    	.eshoppanels a span {position:absolute;top:-9999px;left:-9999px;}
    	</style>
    	<?php endif;
    
    	// Site title font
    	if( isset( $emporium_options['header_font'] ) && $emporium_options['header_font'] != 'Default' ) :
    	switch ($emporium_options['header_font']) {
    
    		case 'Fredericka';
    		$font = 'Fredericka';
    		$family = 'serif';
    		$font_size = '2.3em;';
    		$font_face = "@font-face {font-family:Fredericka;
    		src: url('" . get_template_directory_uri() . "/fonts/FrederickatheGreat-Regular.ttf'),
    		url('" . get_template_directory_uri() . "/fonts/FrederickatheGreat-Regular.ttf');}";
    		break;
    
    		case 'HennyPenny';
    		$font = 'HennyPenny';
    		$family = 'serif';
    		$font_size = '2.8em;';
    		$font_face = "@font-face {font-family:HennyPenny;
    		src: url('" . get_template_directory_uri() . "/fonts/HennyPenny-Regular.ttf'),
    		url('" . get_template_directory_uri() . "/fonts/HennyPenny-Regular.ttf');}";
    		break;
    
    		case 'NovaSlim';
    		$font = 'NovaSlim';
    		$family = 'sans-serif';
    		$font_size = '2.5em;';
    		$font_face = "@font-face {font-family:NovaSlim;
    		src: url('". get_template_directory_uri() . "/fonts/NovaSlim.ttf'),
    		url('" . get_template_directory_uri() . "/fonts/NovaSlim.ttf');}";
    		break;
    
    		case 'Sofia';
    		$font = 'Sofia';
    		$family = 'cursive';
    		$font_size = '3em;';
    		$font_face = "@font-face {font-family:Sofia;
    		src: url('" . get_template_directory_uri() . "/fonts/Sofia-Regular.ttf'),
    		url('" . get_template_directory_uri() . "/fonts/Sofia-Regular.ttf');}";
    		break;
    
    		case 'Milonga';
    		$font = 'Milonga';
    		$family = 'serif';
    		$font_size = '2.5em;';
    		$font_face = "@font-face {font-family:Milonga;
    		src: url('" . get_template_directory_uri() . "/fonts/Milonga-Regular.ttf'),
    		url('" . get_template_directory_uri() . "/fonts/Milonga-Regular.ttf');}";
    		break;
    
    		case 'CabinSketch';
    		$font = 'CabinSketch';
    		$family = 'cursive';
    		$font_size = '2.7em;';
    		$font_face = "@font-face {font-family:CabinSketch;
    		src: url('" . get_template_directory_uri() . "/fonts/CabinSketch-Regular.ttf'),
    		url('" . get_template_directory_uri() . "/fonts/CabinSketch-Regula.ttf');}";
    		break;
    
    	}
    	?>
    	<style type = "text/css">
    	<?php echo $font_face;?>
    	#header h1 {font-family:<?php echo $font;?>, <?php echo $family;?>;font-size:<?php echo $font_size;?>;}
    	</style>
    	<?php endif;
    }
    endif;
    add_action( 'wp_head', 'emporium_style' );
    
    // Output sidebar positioning
    if( !function_exists( 'emporium_sidebar_position') ) :
    function emporium_sidebar_position() {
    	global $emporium_options;
    	if( isset( $emporium_options['sidebar_position'] ) && $emporium_options['sidebar_position'] == 'right' ) {
    		$emporium_c = 'left';
    		$emporium_v = 'right';
    		$emporium_innerwrap_bg = 'sidebar-right.png';
    	}
    	else {
    		$emporium_c = 'right';
    		$emporium_v = 'left';
    		$emporium_innerwrap_bg = 'sidebar-left.png';
    	}
    	?>
    <style type = "text/css">
    #content {float:<?php echo $emporium_c;?>;margin-<?php echo $emporium_c;?>:20px;}
    #vertical {float:<?php echo $emporium_v;?>;}
    #innerwrap {background-image:url(<?php echo get_stylesheet_directory_uri() . '/images/' . $emporium_innerwrap_bg;?>);background-position:<?php echo $emporium_v;?>}
    #vertical .wrapper {top;margin-<?php echo $emporium_c;?>:23px;margin-<?php echo $emporium_v;?>:2px;}
    </style>
    	<?php
    }
    endif;
    add_action( 'wp_head', 'emporium_sidebar_position' );

    Okey, first off, thank you for trying to help me Esmi. It’s really appreciated.

    But, If I would consider outputting the CSS code in the head of the HTML-document a reasonable solution I wouldn’t have asked this question in the first place. It’s way to much CSS to send along with every request in my case.

    All I really wanted to know (which i tried to explain in my first post) was if there is a “best practice” when you want to bootstrap wordpress from a file within a theme or a plugin. I’m starting to think there isn’t 🙂

    Hi, victor_jonsson.

    I have also been interested in implementing dynamic CSS. My rough idea is to use the Rewrite API. I might learn from the way of making feed content. But I haven’t done it.

    Another posibility is the way of localizing scripts with wp_localize_script. But it seems that we don’t have any similar functions for CSS registerd by wp_enqueue_style.

    Sorry for being without concrete conclusion.

    Is it possible to take a step back and explain what you are trying to accomplish and what your goals are?

    Are you trying to avoid bootstrapping WordPress altogether?

    Are you trying to build a plugin/theme that is not dependent on a specific/hardcoded WordPress install location?

    Is this single use code and customizations/hardcoding is acceptable?

    Are you trying to optimize for server performance?

    Are you trying to optimize for client side performance?

    Do you really need to generate CSS on the fly on any given page load?

    From your last post:

    All I really wanted to know (which i tried to explain in my first post) was if there is a “best practice” when you want to bootstrap wordpress from a file within a theme or a plugin. I’m starting to think there isn’t 🙂

    If that is really all you want to know, then you are probably looking at using the query_vars filter and parse_request action hooks. This will allow you to generically leverage WordPress without having to know or care where WordPress is installed.

    Are you trying to avoid bootstrapping WordPress altogether?
    I guess so. I want to bootstrap only what is needed to get access to the most basic functionality in WordPress. Ideally, WordPress shouldn’t parse the request since that wouldn’t be necessary in this case. If it’s possible to hook into the request parsing process that might be an option.

    Are you trying to build a plugin/theme that is not dependent on a specific/hardcoded WordPress install location?

    Yes, this would be done in a theme. And yes, I don’t want to write code that makes to much assumptions about how the files is structured in the application. I know this makes me come of as pedantic since probably 99.99% of all WordPress applications has the same file structure. But never the less, include '/../../some-file.php'does feel really hard coded and it makes wanna hurl when I’m forced to put code like that in my software 🙂

    Is this single use code and customizations/hardcoding is acceptable?

    There you “hit your head on the nail” (old Swedish saying 🙂 ). It probably is acceptable. I just thought that I should ask you wp pros if there is any alternative solutions that would be preferable.

    Are you trying to optimize for server performance? / Are you trying to optimize for client side performance?

    I would prioritize the client side performance in this case. Like a said in an earlier post, I could simply write the generated CSS to a file and enqueue it but I felt that my programming logic would become more complex in that case (but I might end up using this solution anyway)

    Do you really need to generate CSS on the fly on any given page load?

    The answer would be yes!

    Thanks so much for your input Ming. I will look into query_vars and parse_request!

    / vic

Viewing 15 replies - 1 through 15 (of 21 total)
  • The topic ‘Best way to create a css file dynamically’ is closed to new replies.