purazumakoiの[はてなブログ]

技術メモから最近はライフログも増えてきてます。

括弧([])をリテラル化する

phpMyFAQにはリテラル化するタグは用意されていないようだ

phpMyFAQはどうやら独自のテンプレートで動いてるようだが


phpMyFAQにはsmartyの{literal}タグみたいなのがどうも見つからなかった。これでは
[]の文字が使えないので
IEのみにCSSを当てる

[if (gte IE 5 & lt IE 7)]

の文が使えない

smartyの{literal}タグみたいなのを実装したかった

が実際は退避させて解決しているので結果としては同じような動きはするだけ。
二つのfunction内を編集


inc/Template.php

public function processTemplate($templateName, Array $templateContent)
{

    $tmp       = $this->templates[$templateName];
		$rawBlocks = $this->_readBlocks($tmp);

		// リテラルはリテラル文字にて退避
		$cha_literal = "__PMF__LITERAL__";
		
		// 退避リテラル指定
		$arr_literal = array();
		$arr_literal[] = '[if (gte IE 5 & lt IE 7)]';
		$arr_literal[] = '[endif]';
		
		// リテラル退避処理
		for($i=0; $i<count($arr_literal); $i++) {
			$tmp = str_replace($arr_literal[$i], $cha_literal.$i, $tmp);
		}

    // process blocked content
    if (isset($this->blocks[$templateName])) {
			  foreach ($rawBlocks as $key => $rawBlock) {
            if (in_array($key, $this->blocksTouched) && $key != 'unblocked') {
                $tmp = str_replace($rawBlock, $this->blocks[$templateName][$key], $tmp);
					      $tmp = preg_replace('/\[.+\]/', '', $tmp);
            } elseif ($key != 'unblocked') {
                $tmp = str_replace($rawBlock, '', $tmp);
                $tmp = preg_replace('/\[.+\]/', '', $tmp);
            }
        }
    }
		
    // process unblocked content
    if (isset($this->blocks[$templateName]['unblocked'])) {
        $templateContent = $this->_checkContent($templateContent);
        foreach ($this->blocks[$templateName]['unblocked'] as $tplVar) {
            $varName = preg_replace('/[\{\}]/', '', $tplVar);
            if (isset($templateContent[$varName])) {
                $tmp = str_replace($tplVar, $templateContent[$varName], $tmp);
            }
        }
    }
		// リテラル復元処理
		for($i=0; $i<count($arr_literal); $i++) {
			$tmp = str_replace($cha_literal.$i, $arr_literal[$i], $tmp);
		}

    if (isset($this->outputs[$templateName])) {
        $this->outputs[$templateName] .= $tmp;
    } else {
        $this->outputs[$templateName] = $tmp;
    }
}


同じファイル内にもう一か所
inc/Template.php

private function _readBlocks($tpl)
{
    $tmpBlocks = array();
		
		// リテラルはリテラル文字にて退避
		$cha_literal = "__PMF__LITERAL__";
		
		// 退避リテラル指定
		$arr_literal = array();
		$arr_literal[] = '[if (gte IE 5 & lt IE 7)]';
		$arr_literal[] = '[endif]';
		
		// リテラル退避処理
		for($i=0; $i<count($arr_literal); $i++) {
			$tpl = str_replace($arr_literal[$i], $cha_literal.$i, $tpl);
		}
		
		
    // read all blocks into $tmpBlocks
    preg_match_all('/\[.+\]\s*[\W\w\s\{\}\<\>\=\"\/]*?\s*\[\/.+\]/', $tpl, $tmpBlocks);

    $unblocked = $tpl;
    if (isset($tmpBlocks)) {
        $blockCount = count($tmpBlocks[0]);
        for ($i = 0 ; $i < $blockCount; $i++) {
				
                $name = '';
		//find block name
		preg_match('/\[.+\]/', $tmpBlocks[0][$i], $name);

		$name = preg_replace('/[\[\[\/\]]/', '', $name);

		//remove block tags from block
		$res = str_replace('[' . $name[0] . ']','',$tmpBlocks[0][$i]);
		$res = str_replace('[/' . $name[0] . ']','',$res);
		$tplBlocks[$name[0]] = $res;

		//unblocked content
		$unblocked = str_replace($tplBlocks[$name[0]], '', $unblocked);
		$unblocked = str_replace('[' . $name[0] . ']','',$unblocked);
		$unblocked = str_replace('[/' . $name[0] . ']','',$unblocked);
        }

        $hits = array();
        preg_match_all('/\{.+?\}/', $unblocked, $hits);
        $tplBlocks['unblocked'] = $hits[0];
				
    } else {
        // no blocks defined
        $tplBlocks = $tpl;
    }
    return $tplBlocks;
}


やってることはなんてことはない文字の置き換え

// 退避リテラル指定
$arr_literal = array();
$arr_literal[] = '[if (gte IE 5 & lt IE 7)]';
$arr_literal[] = '[endif]';

使い方としては
この配列にリテラル化したい文字列を入れればよい