Permalink
Browse files

App updates to allow multiple sequential foreach loops

  • Loading branch information...
1 parent 196382d commit 1dc30b8bfa8a69b69097b7e76212a9fddf0161d3 @kolber committed Jan 10, 2010
@@ -18,9 +18,52 @@ static function get_partial_template($name) {
return 'Partial \''.$name.'\' not found';
}
+ static function test_nested_matches($template_parts, $opening, $closing) {
+ # count opening tag matches within the opening and closing references
+ preg_match_all('/'.$opening.'/', $template_parts[count($template_parts) - 2], $opening_matches);
+ $closing_count = count($opening_matches[0]);
+
+ # if the inner-match contains unclosed opening references
+ if($closing_count > 0) {
+ # expand match to include a balanced number of closing references
+ $template_parts = self::expand_match($closing_count, $template_parts, $opening, $closing);
+ }
+
+ return $template_parts;
+ }
+
+ static function expand_match($closing_count, $template_parts, $opening, $closing) {
+
+ # TODO: This will still break:
+ #
+ # foreach $root do
+ # foreach $children do
+ # # do something
+ # endforeach
+ # foreach $parents do
+ # # do something
+ # endforeach
+ # endforeach
+ #
+
+ # rerun match to include the correct number of closing references,
+ # using a backreference repeated once for each additionally-required closing reference
+ preg_match('/('.$opening.'[\S\s]*?('.$closing.')([\S\s]+?\\2){'.$closing_count.','.$closing_count.'})([\S\s]*)/', $template_parts[0], $matches);
+
+ # strip out first opening and last closing references
+ $matches[1] = preg_replace(array('/^'.$opening.'\s+?/', '/\s+?'.$closing.'$/'), '', $matches[1]);
+
+ # overwrite the last two elements of the $matches array (the contents of the block & everything following the block)
+ $template_parts[count($template_parts) - 1] = $matches[4];
+ $template_parts[count($template_parts) - 2] = $matches[1];
+
+ # return modified matches array
+ return $template_parts;
+ }
+
static function parse($data, $template) {
# parse template
- if(preg_match('/get[\s]+?["\']\/?(.*?)\/?["\']/', $template)) {
+ if(preg_match('/get[\s]+?["\']\/?(.*?)\/?["\']\s+?do\s+?([\S\s]+?)end(?!\w)/', $template)) {
$template = self::parse_get($data, $template);
}
@@ -45,30 +88,52 @@ static function parse($data, $template) {
static function parse_get(&$data, $template) {
# match any gets
- preg_match('/get[\s]+?["\']\/?(.*?)\/?["\']/', $template, $template_parts);
+ preg_match('/([\S\s]*?)get[\s]+?["\']\/?(.*?)\/?["\']\s+?do\s+?([\S\s]+?)end\b([\S\s]*)$/', $template, $template_parts);
+
+ # run the replacements on the pre-"get" part of the partial
+ $template = self::parse($data, $template_parts[1]);
+
# turn route into file path
- $file_path = Helpers::url_to_file_path($template_parts[1]);
+ $file_path = Helpers::url_to_file_path($template_parts[2]);
+
+ # store current data
+ $current_data = $data;
+
# if the route exists...
if(file_exists($file_path)) {
- # strip out the get line
- $template = str_replace($template_parts[0], '', $template);
+
+ # check for any nested matches
+ $template_parts = self::test_nested_matches($template_parts, 'get[\s]+?["\']\/?.*?\/?["\']\s+?do', 'end\b');
+
# set data object to match file path
$data = AssetFactory::get($file_path);
+
+ # run the replacements on the inner-"get" part of the partial
+ $template .= self::parse($data, $template_parts[3]);
}
+ $data = $current_data;
+
+ # run the replacements on the post-"get" part of the partial
+ $template .= self::parse($data, $template_parts[4]);
+
return $template;
}
static function parse_foreach($data, $template) {
# split out the partial into the parts Before, Inside, and After the foreach loop
- preg_match('/([\S\s]*?)foreach[\s]+?([\$\@].+?)\s+?do\s+?([\S\s]+)endforeach([\S\s]*)$/', $template, $template_parts);
+ preg_match('/([\S\s]*?)foreach[\s]+?([\$\@].+?)\s+?do\s+?([\S\s]+?)endforeach([\S\s]*)$/', $template, $template_parts);
# run the replacements on the pre-"foreach" part of the partial
$template = self::parse($data, $template_parts[1]);
# traverse one level deeper into the data hierachy
$pages = (isset($data[$template_parts[2]]) && is_array($data[$template_parts[2]]) && !empty($data[$template_parts[2]])) ? $data[$template_parts[2]] : false;
+ # check for any nested matches
+ $template_parts = self::test_nested_matches($template_parts, 'foreach[\s]+?[\$\@].+?\s+?do\s+?', 'endforeach');
+
if($pages) {
+
foreach($pages as $data_item) {
# transform data_item into its appropriate Object
$data_object =& AssetFactory::get($data_item);
@@ -88,18 +153,21 @@ static function parse_if($data, $template) {
# run the replacements on the pre-"if" part of the partial
$template = self::parse($data, $template_parts[1]);
+ # check for any nested matches
+ $template_parts = self::test_nested_matches($template_parts, 'if\s*?!?\s*?[\$\@].+?\s+?do\s+?', 'endif');
+
# if statment expects a false result
if($template_parts[2]) {
if(!isset($data[$template_parts[3]]) || (empty($data[$template_parts[3]]) || !$data[$template_parts[3]])) {
# parse the block inside the if statement
- $template .= $template_parts[4];
+ $template .= self::parse($data, $template_parts[4]);
}
}
# if statment expects a true result
else {
if(isset($data[$template_parts[3]]) && !empty($data[$template_parts[3]]) && ($data[$template_parts[3]])) {
# parse the block inside the if statement
- $template .= $template_parts[4];
+ $template .= self::parse($data, $template_parts[4]);
}
}
@@ -1,3 +1,25 @@
-:column1
-:column2
-:column3
+get "/projects" do
+ <div class="column delimit"><h4>Column 1</h4>
+ <ul>
+ foreach $column1 do
+ <li><p><a href="@url">@project_title</a> <span class="project-keywords">@project_keywords</span></p></li>
+ endforeach
+ </ul>
+ </div>
+
+ <div class="column delimit"><h4>Column 2</h4>
+ <ul>
+ foreach $column2 do
+ <li><p><a href="@url">@project_title</a> <span class="project-keywords">@project_keywords</span></p></li>
+ endforeach
+ </ul>
+ </div>
+
+ <div class="column delimit"><h4>Column 3</h4>
+ <ul>
+ foreach $column3 do
+ <li><p><a href="@url">@project_title</a> <span class="project-keywords">@project_keywords</span></p></li>
+ endforeach
+ </ul>
+ </div>
+end
@@ -1,8 +0,0 @@
-get "/projects"
-<div class="column delimit"><h4>Column 1</h4>
- <ul>
- foreach $column1 do
- <li><p><a href="@url">@project_title</a> <span class="project-keywords">@project_keywords</span></p></li>
- endforeach
- </ul>
-</div>
@@ -1,8 +0,0 @@
-get "/projects"
-<div class="column delimit"><h4>Column 2</h4>
- <ul>
- foreach $column2 do
- <li><p><a href="@url">@project_title</a> <span class="project-keywords">@project_keywords</span></p></li>
- endforeach
- </ul>
-</div>
@@ -1,8 +0,0 @@
-get "/projects"
-<div class="column delimit"><h4>Column 3</h4>
- <ul>
- foreach $column3 do
- <li><p><a href="@url">@project_title</a> <span class="project-keywords">@project_keywords</span></p></li>
- endforeach
- </ul>
-</div>

0 comments on commit 1dc30b8

Please sign in to comment.