douyuan4825 2014-10-14 13:51
浏览 34
已采纳

主题的复杂变量提取/ preg_match / replace / shortcodes

Yes, i know i am reinventing the wheel but i do not want to use a framework or templating system.

The idea:

  • Create a theme.php which holds the variables for a page layout ie. $layout['default'],$layout['twocolumn'] etc
  • Read theme.php $layouts
  • Extract the layouts based on some variables ie. The page your viewing
  • preg_match shortcodes within the $layouts ie. {MODULEAREA=1}
  • Return the number of {MODULE= ie. =1 to use in $module
  • Replace the shortcodes with content from the database
  • Return $layout['default'] with all html surrounding it and shortcodes replaced
  • I would also need to grab the layouts for the admin section so i can set the modules in the correct place according to the theme

Note: Header and footer will be separate files "included" in the index.php

Heres what i have so far:

It sometimes replaces the shortcodes but removes all html, ideally i would like to replace the shortcodes and return the html with the new content.

$layout = '
<div class="module_area_one">
{MODULEAREA=1}
</div>
<div class="module_area_two">
{MODULEAREA=2}
</div>
<div class="module_area_three">
{MODULEAREA=3}
</div>
 ';

foreach(parselayout($layout, TRUE) as $module) {
    $row = $dmodule->getModuleByModuleArea($module);
    echo '
    <div class="module_wrap">
            <div class="module_title">'.$row[0]['module_title'].'</div>
            <div class="module_body">'.$row[0]['module_body'].'</div>
        </div>
    ';
}

function parselayout($layout, $check = FALSE) {
$tmp = explode("
", $layout); 
    $str = array();

    for ($c = 0, $cnt = count($tmp); $c < $cnt; $c++) {
        if (preg_match("/[\{|\}]/", $tmp[$c])) {
            if ($check) {
                if (strstr($tmp[$c], "{MODULE=")) {
                    $matches = array();
                    preg_match_all("/\{MODULE=([\d]{1,3})(:[\w\d]*)?\}/", $tmp[$c], $matches);
                    if(!$matches){
                        return;
                    }

                    foreach ($matches[1] as $match) {
                        $ret[] = $match;
                    }
                }
            } 
        } 
        else {
            if (!$check) {
                echo $tmp[$c];
            }
        }
    }
    if ($check) {
        return $str;
    }
}


public function getModuleByModuleArea($moduleMenuArea) {             
    $query = "SELECT module_title, module_name, module_body FROM wcx_modules WHERE module_menu_area=:module_menu_area AND module_active=1";
    $stmt = $this->queryIt($query);
    $stmt = $this->bind(':module_menu_area', $moduleMenuArea);
return $this->resultset();          
}

Update:

OK, so I'm a bit closer, the following code returns the modules in their respective place but it only shows one module which it repeats for all 3 menus, can you see anything wrong here.

I still have to figure out how to add a $layout['default'] = ''; as well.

The preg_match_all:

$pattern = '/\{MENU=([\d]{1,3})(:[\w\d]*)?\}/';
preg_match_all($pattern, $text, $matches); 

//print_r($matches[1]);

foreach($matches[1] as $menu) {
    $row = $dmodule->getModuleByModuleArea($menu);
    $module = '
    <div class="module_wrap">
            <div class="module_title">'.$row[0]['module_title'].'</div>
            <div class="module_body">'.$row[0]['module_body'].'</div>
        </div>
    ';
}
$text = preg_replace($pattern, $module, $text);

echo $text;

The string:

$text = "
<div id='wrapper'>

<div id='maincontainer'>

<div id='leftcolumn'>
{MENU=1}
</div>


<div id='contentcolumn'>
{MENU=3}
</div>


<div id='rightcolumn'>
{MENU=2}
</div>

</div>
</div>

<div id='footer'> 
<div id='footer_disclaim'>

</div>
</div>
";
  • 写回答

1条回答 默认 最新

  • drtkyykai004574380 2014-10-14 19:39
    关注

    Your problem is this:

    preg_match_all($pattern, $text, $matches);
    foreach($matches[1] as $menu) {
        $row = $dmodule->getModuleByModuleArea($menu);
        $module = 'Simplified for readability';
    }
    // Now $module holds the last value calculated in the
    // foreach-loop, and you are replacing all matches
    // with that value.
    $text = preg_replace($pattern, $module, $text);
    

    You should take a look at preg_replace_callback.

    // This function will be called for every match of your
    // regex and the return-value will be used as the replacement
    $replaceCallback = function($matches) use ($dmodule) {
        $menu = $matches[1];
        $row = $dmodule->getModuleByModuleArea($menu);
        $module = 'Simplified for readability';
        return $module;
    };
    $text = preg_replace_callback($pattern, $replaceCallback, $text);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图