2011-12-18 92 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