6

I am working on a theme that uses dynamic in head CSS and gives admin an option to also place the same in a file. Problem is that I am not sure what WP folder is always writable. I originally added the CSS file creation to themename/css/ dir but since WP deletes the theme on update this has become an issue.

What do you think is the best way to approach this and what is the safest writable WP folder that I could use for this feature?

10

Best place is the uploads directory - it'll be writable by the server, and it's the defacto directory for storing any user-generated/uploaded files:

$dirs = wp_upload_dir();
$path = $dirs['basedir']; // /path/to/wordpress/wp-content/uploads
  • it is $dirs['basedir'] , you might want to edit the anwser. thx! – Benn May 14 '16 at 10:36
  • Good spot, done. – TheDeadMedic May 14 '16 at 10:37
4

The only directory with guaranteed write access is the upload directory. Everything else might be protected.

Nowadays, we deploy sites with Composer, keep everything under version control and create completely new sites with each deploy in order to be able to roll back the deployed site. That means that the directory will be created completely new with each deploy.

Use the uploads directory if you have to write files, becase that's the only one that is kept (outside of the other directories).

2

One alternative approach us to have a PHP file that gets the theme options and outputs the CSS and enqueue that directly instead. eg.

wp_enqueue_style('custom-css',trailingslashit(get_template_directory_uri()).'styles.php');

This may seem like a strange thing to do at first, but since actually writing a new file should be done via the WP Filesystem for correct owner/group permissions, this is one way around that problem.

// send CSS Header
header("Content-type: text/css; charset: UTF-8");

// faster load by reducing memory with SHORTINIT
define('SHORTINIT', true);

// recursively find WordPress load
function find_require($file,$folder=null) {
    if ($folder === null) {$folder = dirname(__FILE__);}
    $path = $folder.DIRECTORY_SEPARATOR.$file;
    if (file_exists($path)) {require($path); return $folder;}
    else {
        $upfolder = find_require($file,dirname($folder));
        if ($upfolder != '') {return $upfolder;}
    }
}

// load WordPress core (minimal)
$wp_root_path = find_require('wp-load.php');
define('ABSPATH', $wp_root_path);
define('WPINC', 'wp-includes');

At this point you will need to include whatever other wp-includes files you need to get the theme options, which may vary depending on your how you are saving those. (You will probably need to add more so you do not get fatal errors.) eg.

include(ABSPATH.WPINC.DIRECTORY_SEPARATOR.'version.php');
include(ABSPATH.WPINC.DIRECTORY_SEPARATOR.'general-template.php');
include(ABSPATH.WPINC.DIRECTORY_SEPARATOR.'link-template.php');

Then just output the CSS options... eg.

echo 'body {color:' . get_theme_mod('body_color') . ';}';
echo 'body {backgroundcolor:' . get_theme_mod('body_background_color') . ';}';
exit;
0

I think the best place to write to is to add a folder in the wp-content folder. Here you can write your css files without it is being overwritten when you have a theme update or have a WP update.

  • You don't even know if you have write access there. – fuxia May 14 '16 at 10:14
  • Wp-content Should be writable for uploading plug-ins, themes or media. So i think this the best place to start – Jorin van Vilsteren May 14 '16 at 10:24
  • 1
    No, it should not be writable when you handle plugins and themes with automation tools. A wp-content doesn't even have to exist, because you can customize every path in there. – fuxia May 14 '16 at 10:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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