source: spip-zone/_plugins_/less-css/trunk/lesscss_fonctions.php @ 48831

Last change on this file since 48831 was 48831, checked in by cedric@…, 10 years ago

(oups, il manquait un morceau de commit dans r48830)
Ne pas compiler une meme less deux fois dans le hit (cas si echec au premier coup)
Generer une erreur de compilation SPIP en cas d'erreur de compilation LESS
Definir le importDir de la LESS compilee pour résoudre les @import less
Corriger un bug sur l'import qui provoque une erreur fatale si le fichier importé commence par des commentaires (on fix ici sans reporter au dev de lessPHP car le modele interne de compilation LESS a completement changé depuis cette release)

  • Property svn:executable set to *
File size: 4.1 KB
Line 
1<?php
2
3/**
4 * Compiler des styles inline LESS en CSS
5 * @param string $style
6 * @return string
7 */
8function less_compile($style, $import_dir="", $contexte = array()){
9        require_once 'lessphp/lessc.inc.php';
10
11        // le compilateur lessc compile le contenu
12        $less = new lessc();
13        if ($import_dir){
14                $less->importDir = rtrim($import_dir,"/")."/";
15        }
16        try {
17                $out = $less->parse($style);
18                return $out;
19        }
20        // en cas d'erreur, on retourne du vide...
21        catch (exception $ex) {
22                spip_log('lessc fatal error:'.$ex->getMessage(),'less'._LOG_ERREUR);
23                erreur_squelette(
24                        "LESS : Echec compilation"
25                        . (isset($contexte['file'])?" fichier ".$contexte['file']:"")
26                  . "<br />".$ex->getMessage()
27                );
28                return '';
29        }
30}
31
32/**
33 * Transformer du LESS en CSS
34 * Peut prendre en entree
35 * - un fichier .css ou .less :
36 *   [(#CHEMIN{messtyles.less.css}|less_css)]
37 *   la sortie est un chemin vers un fichier CSS
38 * - des styles inline,
39 *   pour appliquer dans une feulle less calculee :
40 *   #FILTRE{less_css}
41 *   la sortie est du style inline
42 *
43 * @param string $source
44 * @return string
45 */
46function less_css($source){
47        // Si on n'importe pas, est-ce un fichier ?
48        if (!preg_match(',[\s{}],', $source)
49          AND preg_match(',\.(less|css)$,i', $source, $r)
50          AND file_exists($source)) {
51                static $done = array();
52                // ne pas essayer de compiler deux fois le meme fichier dans le meme hit
53                // si on a echoue une fois, on echouera pareil
54                if (isset($done[$source])) return $done[$source];
55
56                $f = basename($source,$r[0]);
57                $f = sous_repertoire (_DIR_VAR, 'cache-less')
58                . preg_replace(",(.*?)(_rtl|_ltr)?$,","\\1-cssify-"
59                . substr(md5("$source-lesscss"), 0,4) . "\\2", $f, 1)
60                . '.css';
61
62                # si la feuille compilee est plus recente que la feuille source
63                # l'utiliser sans rien faire, sauf si recalcul explicite
64                if ((@filemtime($f) > @filemtime($source))
65                  AND (!defined('_VAR_MODE') OR _VAR_MODE != 'recalcul'))
66                        return $f;
67
68                if (!lire_fichier($source, $contenu))
69                        return $source;
70
71                # compiler le LESS
72                $contenu = less_compile($contenu, dirname($source), array('file'=>$source));
73                // si erreur de compilation on renvoit la source, et il y a deja eu un log
74                if (!$contenu)
75                        return $done[$source] = $source;
76                # passer la css en url absolue (on ne peut pas le faire avant, car c'est du LESS, pas des CSS)
77                $contenu = urls_absolues_css($contenu, $source);
78
79                // ecrire le fichier destination, en cas d'echec renvoyer la source
80                if (ecrire_fichier($f, $contenu, true))
81                        return $done[$source] = $f;
82                else
83                        return $done[$source] = $source;
84        }
85        $source = less_compile($source);
86        if (!$source)
87                return "/* Erreur compilation LESS : cf less.log */";
88        else
89                return $source;
90}
91
92
93/**
94 * injecter l'appel au compresseur sous la forme de filtre
95 * pour intervenir sur l'ensemble du head
96 * du squelette public
97 *
98 * @param string $flux
99 * @return string
100 */
101function lesscss_insert_head($flux){
102        $flux .= '<'
103                .'?php header("X-Spip-Filtre: '
104                .'cssify_head'
105                .'"); ?'.'>';
106        return $flux;
107}
108
109
110/**
111 * Attraper automatiquement toutes les .less ou .less.css du head
112 * les compiler, et les remplacer par leur css compilee
113 *
114 * @param string $head
115 * @return void
116 */
117function cssify_head($head){
118        $url_base = url_de_base();
119        $balises = extraire_balises($head,'link');
120        $files = array();
121        foreach ($balises as $s){
122                if (extraire_attribut($s, 'rel') === 'stylesheet'
123                        AND (!($type = extraire_attribut($s, 'type')) OR $type == 'text/css')
124                        AND $src = extraire_attribut($s, 'href')
125                        // format .less.css ou .less avec un eventuel timestamp ?123456
126                        AND preg_match(",\.(less\.css|less)(\?\d+)?$,",$src)
127                        AND $src = preg_replace(",\?\d+$,","",$src)
128                        AND $src = preg_replace(",^$url_base,",_DIR_RACINE,$src)
129                        AND file_exists($src))
130                        $files[$s] = $src;
131        }
132
133        if (!count($files))
134                return $head;
135
136        foreach($files as $s=>$lessfile){
137                $cssfile = less_css($lessfile);
138                $m = @filemtime($cssfile);
139                $s2 = inserer_attribut($s,"href","$cssfile?$m");
140                $head = str_replace($s, $s2, $head);
141        }
142       
143        return $head;
144}
145?>
Note: See TracBrowser for help on using the repository browser.