2011-12-18 133 views
0

我正在构建一个“主题构建器”,可以动态地动态编辑CSS文件。我想用PHP将是最简单的选择(愿意考虑替代方法)。str_replace基于CSS评论的CSS属性

我的CSS文件中包含像这样每个属性后评论:

html,body { 
    background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/ 
    color: #fff; /*{textColor}*/ 
} 

是否可以使用替换功能,查找该评论之前它仅替换代码?用户在完成构建主题并再次更改内容后可能想要返回,因此评论必须始终保持不变。

感谢

+0

向一个具体的问题,你跑?只需在该行末尾重新添加注释,它应该没问题。 – hakre 2011-12-18 13:54:14

+0

啊我明白了。在这种情况下,我将如何搜索评论,然后替换整个行? – tctc91 2011-12-18 14:02:02

+1

预期产量是多少?第一行不明确,因为'bgColor'属性转换为'background-color'。 – 2011-12-18 14:08:59

回答

1

你产生的页面加载CSS,或者当主题被添加你再生一个CSS文件?

如果您在编辑主题时生成CSS,则可以这样做;

/*bodybg*/ background: #fff url(../images/bg.jpg) repeat-x; /*/bodybg*/

你可以这样做:

$shortCode = bodybg 
$cssContents = preg_replace("/(\/\*".$shortCode."\*\/).*?(\/\*\/".$shortCode."\*\/)/i", 
          "\\1 background: #F00; \\2", 
          $cssContents); 

如果生成的页面加载CSS,你可以这样做:

background: {{bodyBgColor}} url(../images/bg.jpg) repeat-x;

$cssContents = str_replace("{{bodyBgColor}}", $color, $cssContents);

+0

我有一个窗体和一个iframe的页面。 iframe正在加载主题的预览。当用户更新表单时(例如 - 更改背景颜色字段),我希望它在CSS文件上执行PHP替换功能。由于该字段可能会被多次编辑,所以CSS注释必须保留,以便每次都可以通过替换函数来引用它。不知道这是否有道理,但希望它。 – tctc91 2011-12-18 14:23:48

1

难道几年前与此类似的东西,但是我如何做到这一点,就是在加载时在CSS(或者PHP)文件中读取会话变量。

所以...如果你创建一个PHP文件,将作为您的CSS文件,并拷贝到这个...

header("Content-type: text/css"); 
// setup replacement variables here... 
// NOTE: if using the session object to start the session 
// as the stylesheet is running in a seperate process as the rest of the site... 

$textColor = "#ff0000";  // This is a variable that will appear in the CSS 

$fHandle = @fopen("site.css", "r"); // Change this to your CSS file... 
if ($fHandle) { 
    while (($line = fgets($fHandle, 4096)) !== false) { 
     $variable = getTextBetween($line,"/*{","}*/"); 
     if ($variable != ""){ 
      if (isSet($$variable)){ 
       // we have that variable... now what to actually do with it... 
       // what we are going to do is rebuild the line... 
       $attribute = getTextBetween($line,0,":"); 
       // and thats it really... 
       echo($attribute.":".$$variable.";".chr(10)); // NOTE: Double $$ to access the string as a variable :) 
      } else { 
       // that variable does not exist. Just output the line 
       echo $line; 
      } 
     } else { 
      // there is no variable just output the line 
      echo $line; 
     } 
    } 
    fclose($fHandle); 
} 

function getTextBetween($string_in,$start_in,$end_in){ 
    $_start = 0; 
    $_end = 0; 
    // calculate the start and the end points. 
    if (is_string($start_in)){ 
     $_start = strpos($string_in,$start_in); 
     if ($_start === false){ 
      $_start = 0; 
     } else { 
      $_start += strlen($start_in); 
     } 
    } else if (is_numeric($start_in)){ 
     $_start = $start_in; 
    } 

    if (is_string($end_in)){ 
     $_end = strpos($string_in,$end_in,$_start); 
     if ($_end === false) $_end = 0; 
    } else if (is_numeric($end_in)){ 
     $_end = $end_in; 
    } 

    $_return = substr($string_in,$_start,($_end-$_start)); 

    return trim($_return); 
} 

然后包括以同样的方式作为一个正常的样式表文件.. 。

如果你设置所有的变量相同的名称,你的榜样...它会工作,你如何想它,您无需更改任何代码,以满足处事:)

其他的工作方式

如果您需要任何帮助,请让我知道:)

祝你好运:)

爱所有:)

+0

在这种情况下,我宁愿只使用echo来输出用户变量,将CSS文件编写为PHP文件。与常规HTML相同,只是使用不同的内容类型:) – Svish 2011-12-18 15:08:03

+0

这是非常真实的...而不是添加小功能来调整已写入的具有注释的CSS文件...可以将CSS文件重写为PHP文件,改变内容类型和你有需要改变的项目,而不是注释有变量...添加回声基于变量是否存在或不... ...像... echo(isSet($ textColor )?$ textColor:“#fff;”);好点Svish :) – 2011-12-18 16:00:28

2

只要你按照你有varname在该行的结束,每一行包含一个CSS property : value而已,你可以在模式用正则表达式进行搜索和替换。

如果您想这样做,请注意新值在PCRE意义上不包含任何newline-ish:\r\n|\n|\x0b|\f|\r|\x85(非UTF-8模式)。如果你不这样做,这会破坏你的解析器!

要做到这一点,你可以创建为图案的面具,让你可以再插入VARNAME以后很容易,我通常使用sprintf为:

$patternMask = 
'~ 
^# start of line 

    (\s*[a-z]+:\s*) 
    # Group 1: 
    # whitespace (indentation) 
    # + CSS property and ":" 
    # + optional whitespace 

    (.*?) # Group 2: CSS value (to replace) 

    (\s*/\*\{%s\}\*/\s*) 
    # Group 3: 
    # whitespace (after value and before variable) 
    # + variable comment, %%s is placeholder for it\'s name 

    $ # end of line 

    # Pattern Modifiers: 
    # m:^& $ match begin/end of each line 
    # x: ignore spaces in pattern and allow comments (#) 
    ~mx' 
; 

这与评论的正则表达式模式,做成可能与x-修改。只是让你理解起来更容易。

重要的一点是多线模式下的m-修改器。该模式应该适用于每一行,因此它被包含在^(Begin)和$(End)中,它将与多行模式下行的开始和结束相匹配。

当您进行替换操作时,组2将被替换,组1和3将被保留。完成后,结果仍将包含变量名称。

实际的正则表达式,然后通过使用sprintfpreg_quote添加适当的引用变量名到其与此面膜建设:

$varName = 'bgColor'; 
$value = '#f00 url(../images/bg-reg.jpg) repeat-x;'; 

# create regex pattern based on varname 
$pattern = sprintf($patternMask, preg_quote($varName, $patternMask[0])); 

$patternMask[0]~因此,如果您的变数名称将包含~这将是适当的自动转义。

搜索模式现在已完成。剩下的就是更换。作为变量名称,替换字符串也需要转义,以不破坏正则表达式(语法错误)。此外,如前所述,整个过程需要注意将新字符串保留为单行,否则下次执行替换操作会使其断行。因此,为了防止这种情况,任何换行符将在$value用一个空格代替,以防止:

# replace characters that will break the pattern with space 
$valueFiltered = str_replace(explode('|', "\r\n|\n|\x0b|\f|\r|\x85"), ' ', $value); 

然后特​​殊字符\$将被引用,使他们不会替换模式和干扰替换字符串是建立。这与addcslashes函数来完成:

# escape $ characters as they have a special meaning in the replace string 
$valueEscaped = addcslashes($valueFiltered, '\$'); 
$replace = sprintf('${1}%s$3', $valueEscaped); 

剩下的唯一的事情就是运行更换操作,所以给它ssome CSS前期:

$css = <<<CSS 
html,body { 
    background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/ 
    color: #fff; /*{textColor}*/ 
} 
CSS; 

并运行preg_replace替换:

$newCss = preg_replace($pattern, $replace, $css); 

这已经是整件事了。从最初的CSS:

html,body { 
    background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/ 
    color: #fff; /*{textColor}*/ 
} 

要结果CSS:

html,body { 
    background: #f00 url(../images/bg-reg.jpg) repeat-x; /*{bgColor}*/ 
    color: #fff; /*{textColor}*/ 
} 

如果你使用preg_replace&$count参数,你可以检查,如果变量是字符串的一部分:

$newCss = preg_replace($pattern, $replace, $css, -1, $count); 

$count在给出的示例中为1。

如果您想一次替换多个值,则可以使用数组作为$pattern$replace以防万一它有帮助。 $count仍然是一个整数,所以它可能是有限的使用。

一览整个代码:

$css = <<<CSS 
html,body { 
    background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/ 
    color: #fff; /*{textColor}*/ 
} 
CSS; 


$patternMask = 
'~ 
^# start of line 

    (\s*[a-z]+:\s*) 
    # Group 1: 
    # whitespace (indentation) 
    # + CSS property and ":" 
    # + optional whitespace 

    (.*?) # Group 2: CSS value (to replace) 

    (\s*/\*\{%s\}\*/\s*) 
    # Group 3: 
    # whitespace (after value and before variable) 
    # + variable comment, %%s is placeholder for it\'s name 

    $ # end of line 

    # Pattern Modifiers: 
    # m:^& $ match begin/end of each line 
    # x: ignore spaces in pattern and allow comments (#) 
    ~mx' 
; 

$varName = 'bgColor'; 
$value = '#f00 url(../images/bg-reg.jpg) repeat-x;'; 

# create regex pattern based on varname 
$pattern = sprintf($patternMask, preg_quote($varName, $patternMask[0])); 

# replace characters that will break the pattern with space 
$valueFiltered = str_replace(explode('|', "\r\n|\n|\x0b|\f|\r|\x85"), ' ', $value); 

# escape $ characters as they have a special meaning in the replace string 
$valueEscaped = addcslashes($valueFiltered, '\$'); 

$replace = sprintf('${1}%s$3', $valueEscaped); 

$newCss = preg_replace($pattern, $replace, $css); 

echo $newCss; 
+0

+1为非常详细的解释 – Kaii 2011-12-19 13:33:42