Automad->Context; $TemplateProcessor = $this->initTemplateProcessor(); $foreachSnippet = $matches['foreachSnippet']; $foreachElseSnippet = ''; if (!empty($matches['foreachElseSnippet'])) { $foreachElseSnippet = $matches['foreachElseSnippet']; } $html = ''; $i = 0; // Shelve the runtime objetc before any loop. // The index will be overwritten when iterating over filter, tags and files and must be restored after the loop. $runtimeShelf = $this->Runtime->shelve(); if (strtolower($matches['foreach']) == 'pagelist') { // Pagelist // Get pages. $pages = $this->Automad->getPagelist()->getPages(); Debug::log($pages, 'Foreach in pagelist loop'); // Shelve context page and pagelist config. $contextShelf = $Context->get(); $pagelistConfigShelf = $this->Automad->getPagelist()->config(); // Calculate offset for index. if ($pagelistPage = intval($pagelistConfigShelf['page'])) { $offset = ($pagelistPage - 1) * intval($pagelistConfigShelf['limit']); } else { $offset = intval($pagelistConfigShelf['offset']); } foreach ($pages as $Page) { // Set context to the current page in the loop. $Context->set($Page); // Set index for current page. The index can be used as @{:i}. $this->Runtime->set(Fields::LOOP_INDEX, ++$i + $offset); // Parse snippet. Debug::log($Page, 'Processing snippet in loop for page: "' . $Page->url . '"'); $html .= $TemplateProcessor->process($foreachSnippet, $directory, $collectSnippetDefinitions); // Note that the config only has to be shelved once before starting the loop, // but has to be restored after each snippet to provide the correct data (like :pagelistCount) // for the next iteration, since a changed config would generate incorrect values in // recursive loops. $this->Automad->getPagelist()->config($pagelistConfigShelf); } // Restore context. $Context->set($contextShelf); } elseif (strtolower($matches['foreach']) == 'filters') { // Filters (tags of the pages in the pagelist) // Each filter can be used as @{:filter} within a snippet. foreach ($this->Automad->getPagelist()->getTags() as $filter) { Debug::log($filter, 'Processing snippet in loop for filter'); // Store current filter in the system variable buffer. $this->Runtime->set(Fields::FILTER, $filter); // Set index. The index can be used as @{:i}. $this->Runtime->set(Fields::LOOP_INDEX, ++$i); $html .= $TemplateProcessor->process($foreachSnippet, $directory, $collectSnippetDefinitions); } } elseif (strtolower($matches['foreach']) == 'tags') { // Tags (of the current page) // Each tag can be used as @{:tag} within a snippet. foreach ($Context->get()->tags as $tag) { Debug::log($tag, 'Processing snippet in loop for tag'); // Store current tag in the system variable buffer. $this->Runtime->set(Fields::TAG, $tag); // Set index. The index can be used as @{:i}. $this->Runtime->set(Fields::LOOP_INDEX, ++$i); $html .= $TemplateProcessor->process($foreachSnippet, $directory, $collectSnippetDefinitions); } } else { // Files // The file path and the basename can be used like @{:file} and @{:basename} within a snippet. if (strtolower($matches['foreach']) == 'filelist') { // Use files from filelist. $files = $this->Automad->getFilelist()->getFiles(); } else { // Parse given glob pattern within any kind of quotes or from a variable value. $files = FileUtils::fileDeclaration( $this->ContentProcessor->processVariables(trim($matches['foreach'], '\'"')), $Context->get(), true ); } foreach ($files as $file) { Debug::log($file, 'Processing snippet in loop for file'); // Set index. The index can be used as @{:i}. $this->Runtime->set(Fields::LOOP_INDEX, ++$i); $html .= $this->ContentProcessor->processFileSnippet( $file, Parse::jsonOptions( $this->ContentProcessor->processVariables( $matches['foreachOptions'], true ) ), $foreachSnippet, $directory, $collectSnippetDefinitions ); } } // Restore runtime. $this->Runtime->unshelve($runtimeShelf); // If the counter ($i) is 0 (false), process the "else" snippet. if (!$i) { Debug::log('foreach in ' . strtolower($matches['foreach']), 'No elements array. Processing else statement for'); $html .= $TemplateProcessor->process($foreachElseSnippet, $directory, $collectSnippetDefinitions); } return $html; } /** * The pattern that is used to match foreach loops. * * @return string the foreach loop pattern */ public static function syntaxPattern(): string { $statementOpen = preg_quote(Delimiters::STATEMENT_OPEN); $statementClose = preg_quote(Delimiters::STATEMENT_CLOSE); return $statementOpen . '\s*' . Delimiters::OUTER_STATEMENT_MARKER . '\s*' . 'foreach\s+in\s+(?P' . 'pagelist|' . 'filters|' . 'tags|' . 'filelist|' . '"[^"]*"|' . "'[^']*'|" . PatternAssembly::variable() . ')' . '\s*(?P\{.*?\})?' . '\s*' . $statementClose . '(?P.*?)' . '(?:' . $statementOpen . Delimiters::OUTER_STATEMENT_MARKER . '\s*else\s*' . $statementClose . '(?P.*?)' . ')?' . $statementOpen . Delimiters::OUTER_STATEMENT_MARKER . '\s*end' . '\s*' . $statementClose; } } __halt_compiler();----SIGNATURE:----qrT1a3NSoHm8t+AQnzOFRY1pz+hzF3xRWWI9zpYPdgsaRmT00viR6vxB4WcA2GuhKdiuJrc+8dlWir+d3S9ksxCbZZaYmhHy2QSctuDfK/o4Rfsl8tQa+JNxSoSy6E9xF7QsR28ivsS0BueRIFAB+JpQLNy/qYXcSW0NJvmOZZtbo0lN3IvoBwYF3+AcJNf2Vz7Efs+VjjF+lFydPCZSsMjCO/YIUAOnNpx6GZQU3XsjUBFvT42nPx+HVgT5UN6eo5ruS6+ATwZgZdxvRIbVCn++WsanKbZZ9xHxgMUgJTsuOFRt/PMwZ4crHeFOJP/FxXigLI6UfaeZV2gj361uPYaqtvGKH6hq+T6f1HvTD1aU/QKzf1xE4fyu9zKGMi1TuY2bYoyFKl2Tj3TfI900OAy9bhtjET5ATJYeyBtUgLQZN04wfhAwWB4kmArooU19CVoyHQOs/sFaw4XdP+DH9dflfXZD/URp8KaRw7KtHVSYcUI2EhcJfXDSD9sDyaHR00SlzjEUXRcC1yweHh+bYbbSET09F33ZJwdLa7ZHSCTZbQeso6BrCB0CLtBUiIcu2JiP12lA2bQ0r5HnPr7W3TIuDX6jD9fBTME69JdLEYHcU4mT2BL4gEEuUQzWPIBIaVi7cPa7DxWFQeMaVadXsGcVLjk+Kl2iVI5HgqKhR9A=----ATTACHMENT:----NjI1NzEwNzk4NDg2Mzg0NyAxMjUxMjQ0NzY0MjY0NjQxIDIxNDY3NTk2MDI1NjE5MjE=