De css-URL-paden opnieuw berekenen wanneer u deze naar een andere map verplaatst

Wat is de beste manier om CSS te vertalen, zodat het op een ander pad werkt. Ik heb een paar verschillende bibliotheken bekeken (CrushCSS, minify) en ze lijken alleen over deze service te gaan, samen met het comprimeren van de bestanden (wat ik niet wil doen).

Is mijn beste een regex? Zo ja, wat zijn de mogelijke gevallen die ik zal moeten behandelen?

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');
}

BEWERK:

Ik ben niet geïnteresseerd in 'best practice' of manieren om dit soort problemen te voorkomen. Ik ben alleen geïnteresseerd in hoe de transformatie te doen, zodat de CSS correct blijft in het nieuwe pad.

1

2 antwoord

Ik zou zeggen dat de beste manier is om altijd URL's te gebruiken die relatief zijn ten opzichte van de hoofdmap van uw site. /example/absolute/path.png werkt altijd, ongeacht waar u het CSS-bestand plaatst.

2
toegevoegd
Ze zullen het altijd zijn/zoiets. In uw eigen domein of subdomein zijn ze relatief ten opzichte van/en als u zich in een subdirectory bevindt, worden ze/subdirectory.
toegevoegd de auteur GordonM, de bron
In dat geval denk ik dat je maar twee realistische opties hebt. 1) Maak symlinks in locatie b die verwijzen naar de bestanden op locatie a, zodat beide paden naar de betreffende resource geldig zijn, of b) vervang het CSS-bestand door een PHP-script dat een CSS-bestand uitvoert met de paden die opnieuw worden berekend als dat nodig is. Ik zou de eerste aanraden, omdat de laatste problemen veroorzaakt met het cachegeheugen van de stylesheet.
toegevoegd de auteur GordonM, de bron
Dit is geen optie omdat de css-bestanden al bestaan. Ik ben op zoek naar een manier om ze programmatisch te verplaatsen terwijl ze nog steeds geldig zijn.
toegevoegd de auteur Kendall Hopkins, de bron
Ook in mijn geval kan ik geen absolute paden gebruiken, omdat de basis van de site niet gegarandeerd / is.
toegevoegd de auteur Kendall Hopkins, de bron
In mijn geval kan de site tegelijkertijd vanuit twee verschillende mappen worden bekeken (niet mijn werk). Dus als ik url ('/ path') voor één gebruik, zou het de andere verwijzing doorbreken. Ik heb om relatieve CSS te gebruiken om te werken.
toegevoegd de auteur Kendall Hopkins, de bron

Ik besloot dat ik een beetje code van Minify zou willen refactoren om rekening te houden met de abstracte css-transformatie die ik nodig had.

<?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
toegevoegd