Cómo volver a calcular las rutas de la URL del css al moverlo a una carpeta diferente

¿Cuál es la mejor manera de traducir CSS para que funcione en una ruta diferente? He examinado algunas bibliotecas diferentes (CrushCSS, minify) y parece que solo han realizado este servicio junto con la compresión de los archivos (lo que no quiero hacer).

¿Es mi mejor expresión regular? Si es así, ¿cuáles son todos los casos posibles que necesitaré manejar?

For example, input: /base/my.css

@import url "../another/file.css"
#container {
    background: url('example/relative/path.png');
}
#container2 {
    background: url('/example/absolute/path.png');
}

Expected output: /base/example/path/my.css

@import url "../../../another/file.css"
#container {
    background: url('../relative/path.png');
}
#container2 {
    background: url('/example/absolute/path.png');
}

EDITAR:

No me interesan las "mejores prácticas" ni las formas de evitar este tipo de problema. Solo estoy interesado en cómo hacer la transformación para que el CSS siga siendo correcto en la nueva ruta.

1

2 Respuestas

Yo diría que la mejor manera sería usar siempre las URL relacionadas con la raíz de su sitio. /example/absolute/path.png siempre funcionará, sin importar dónde coloques el archivo CSS.

2
agregado
Siempre van a ser/algo. En tu propio dominio o subdominio estarán relacionados con/y si estás en un subdirectorio, entonces serán/subdirectorio.
agregado el autor GordonM, fuente
En ese caso, entonces creo que solo tienes dos opciones realistas. 1) Cree enlaces simbólicos en la ubicación b que apunten a los archivos en la ubicación a, de modo que ambas rutas al recurso en cuestión sean válidas, o b) reemplace el archivo CSS con un script PHP que genere un archivo CSS con las rutas recomendadas según sea necesario. Yo recomendaría el primero, ya que el último causará problemas con el almacenamiento en caché de la hoja de estilo.
agregado el autor GordonM, fuente
Esta no es una opción ya que los archivos CSS ya existen. Estoy buscando una forma de moverlos programáticamente mientras los mantengo válidos.
agregado el autor Kendall Hopkins, fuente
También en mi caso no puedo usar rutas absolutas ya que no se garantiza que la base del sitio sea /.
agregado el autor Kendall Hopkins, fuente
En mi caso, el sitio se puede ver desde dos directorios diferentes simultáneamente (no es mi tarea). Por lo tanto, si utilizamos url ('/ path') para una, rompería la otra referencia. Tengo para usar el CSS relativo para que funcione.
agregado el autor Kendall Hopkins, fuente

Decidí que refactorizaría algún código de Minify para permitir la transformación abstracta de CSS que necesitaba.

<?php

//This class is heavy borrowed from Minify_ImportProcessor

class CSSImporter
{

    static function changePaths( $content, $current_path, $target_path )
    {
        $current_path = rtrim( $current_path, "/" );
        $target_path = rtrim( $target_path, "/" );
        $current_path_slugs = explode( "/", $current_path );
        $target_path_slugs = explode( "/", $target_path );
        $smallest_count = min( count( $current_path_slugs ), count( $target_path_slugs ) );
        for( $i = 0; $i < $smallest_count && $current_path_slugs[$i] === $target_path_slugs[$i]; $i++ );
        $change_prefix = implode( "/", array_merge( array_fill( 0, count( $target_path_slugs ) - $i, ".." ), array_slice( $current_path_slugs, $i ) ) );
        if( strlen( $change_prefix ) > 0 ) $change_prefix .= "/";

        $content = preg_replace_callback(
            '/
            @import\\s+
            (?:url\\(\\s*)?     # maybe url(
            [\'"]?              # maybe quote
            (.*?)               # 1 = URI
            [\'"]?              # maybe end quote
            (?:\\s*\\))?        # maybe )
            ([a-zA-Z,\\s]*)?    # 2 = media list
            ;                   # end token
            /x',
            function( $m ) use ( $change_prefix ) {
                $url = $change_prefix.$m[1];
                $url = str_replace('/./', '/', $url);
                do {
                    $url = preg_replace('@/(?!\\.\\.?)[^/]+/\\.\\[email protected]', '/', $url, 1, $changed);
                } while( $changed );
                return "@import url('$url'){$m[2]};";
            },
            $content
        );
        $content = preg_replace_callback(
            '/url\\(\\s*([^\\)\\s]+)\\s*\\)/',
            function( $m ) use ( $change_prefix ) {
               //$m[1] is either quoted or not
                $quote = ($m[1][0] === "'" || $m[1][0] === '"')
                    ? $m[1][0]
                    : '';
                $url = ($quote === '')
                    ? $m[1]
                    : substr($m[1], 1, strlen($m[1]) - 2);

                if( '/' !== $url[0] && strpos( $url, '//') === FALSE ) {
                    $url = $change_prefix.$url;
                    $url = str_replace('/./', '/', $url);
                    do {
                        $url = preg_replace('@/(?!\\.\\.?)[^/]+/\\.\\[email protected]', '/', $url, 1, $changed);
                    } while( $changed );
                }
                return "url({$quote}{$url}{$quote})";
            },
            $content
        );
        return $content;
    }

}

?>
2
agregado
PHP - Comunidad española
PHP - Comunidad española
6 de los participantes

En este grupo hablamos de PHP. Partner: es.switch-case.com