Search code examples
phpwordpressapachegulp

Apache. How to move wp-config.php and wp-content outside from wordpress core?


I want to use one wordpress core for all my themes when i develop them on my local machine. For example wordpress core located on C:\xampp\wordpress\www and it has a VirtualHost from Apache https://wordpress.local. Themes located on C:\gulp\projects and here is located all projects (folders) with static websites and here is i want to store all my wp themes in their own folder. Inside of each wp theme folder is wp-config.php and the wp-content folder. I want to store each wp theme folder on git versioning and i planning switch projects by gulp just by replacing paths in wp configs in the core. I plan to do this only on local machine and only for development reasons and i just want push changes on server. I don't want to create a new virtual domain and folders in apache for each new project and i don't want to grab wordpress core to git versioning.

I tried to change paths in configs in the core define( 'WP_CONTENT_DIR', ‘C:\gulp\projects\TEST-WP-THEME\wp-content’ ), but unfortunately wp core can't "see" the directory and there is white screen only when i go to my domain in the browser. I suppose that apache can't "see" directories outside C:\xampp\wordpress\www, but i believe that it is possible to configure apache that it may hook up directories outside from "server". How to hook up external wp-config.php and the wp-content folder to the wp core, who knows how to do this please help me.


Solution

  • After long time i publish my solution. For example: the WP core will be stored in C://wordpress.local/ folder and for that folder we'll create a http://wordpress.local domain. All projects will be in C://projects/. Each project has its own wp-content folder, wp-config-dev.php (for DB credentials and table prefix) and usual wp-config.php that we deploy on the server.

    We'll take a project called example in C://projects/example/wp.

    Core's wp-config.php

    <?php
    $project = 'example';
    define( 'WP_CONTENT_DIR', 'C:/projects/'.$project.'/wp/wp-content' );
    define( 'WP_CONTENT_URL', 'https://projects.folder/'.$project.'/wp/wp-content' );
    include('C:/projects/'.$project.'/wp/wp-config-dev.php');
    if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', dirname( __FILE__ ) . '/' );
    }
    require_once( ABSPATH . 'wp-settings.php' );
    // custom functions (optional)
    include('custom.php');
    

    Project's wp-core-dev.php

    <?php
    define( 'DB_NAME', 'example' );
    define( 'DB_USER', 'root' );
    define( 'DB_PASSWORD', '' );
    define( 'DB_HOST', 'localhost' );
    define( 'DB_CHARSET', 'utf8mb4' );
    define( 'DB_COLLATE', '' );
    $table_prefix = 'wp_';
    

    In additional you have to share your projects folder as domain in Apache's httpd-vhosts.conf

    <Directory "C://projects/*">
        Options Indexes FollowSymLinks Includes ExecCGI
        AllowOverride All
        Require all granted
    </Directory>
    
    # For WP_CONTENT_URL
    <Directory "C://projects">
        Options Indexes FollowSymLinks Includes ExecCGI
        AllowOverride All
        Require all granted
    </Directory>
    <VirtualHost *:80>
        DocumentRoot "C://projects"
        ServerName projects.folder
        # CORS
        Header set Access-Control-Allow-Origin "*"
    </VirtualHost>
    

    And voila, you may switch between projects just with changing the $project variable, personally i do it with bash script and sed.


    Bonus. Put all our projects in WP admin bar and make project selector.

    Add function to your .bashrc

    function wp-set-project {
        local projname="$*"
        # in my case $project is always on second line
        sed -i "2s|.*|\$project = '$projname';|" /c/wordpress.local/wp-config.php
    }
    

    Edit optional custom.php file that we include in core's wp-config.php

    add_action('admin_bar_menu', 'add_project_switch', 999);
    function add_project_switch($admin_bar){
    
    //get current project name from $project variable, read second line from file
    preg_match('/\'(.*?)\'/', file('C://wordpress.local/wp-config.php')[1], $result);
    $currWpProject = $result[1]; //result from second mask without quotes
    
    //get all projects
    $wpProjects = array();
    foreach(glob('C://projects/*/wp', GLOB_ONLYDIR) as $proj) {
        $wpProjects[] = explode('/', $proj)[3]; //get dir name
    }
    
    $admin_bar->add_menu( array(
        'id'    => 'curr-proj',
        'title' => '🚧 Project: '.$currWpProject,
    ));
    
    foreach($wpProjects as $proj) {
        if ($proj !== $currWpProject) {
            $admin_bar->add_menu( array(
                'id'    => 'project-'.$proj,
                'parent' => 'curr-proj',
                'title' => $proj,
                'href'  => '?setWp='.$proj, //make link with get parametr
            ));
        }
    }
    
    }
    
    //Call our bash function if there is passed GET with project name
    $setWp = filter_input( INPUT_GET, 'setWp');
    
    if($setWp){
        //for running bash that way in Windows you have to put your bash.exe in PATH
        shell_exec ('bash -c "source ~/.bashrc && wp-set-project '.$setWp.'"');
        header("Location: "."http://".$_SERVER['HTTP_HOST']);
        exit();
    }
    

    Eventually we got a nice and convenient project selector:

    enter image description here