protected function _runtemplate($template, $data = null) { if ($data === null) $data = $this->data; if (is_array($data)) $data = $this->data->customise($data); $viewer = SSViewer::fromString($template); return $viewer->process($data); }
public function doSearch($gridField, $request) { $dataClass = $gridField->getList()->dataClass(); $allList = $this->searchList ? $this->searchList : DataList::create($dataClass); $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass); if (!$searchFields) { throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass)); } $params = array(); foreach ($searchFields as $searchField) { $name = strpos($searchField, ':') !== FALSE ? $searchField : "{$searchField}:StartsWith"; $params[$name] = $request->getVar('gridfield_relationsearch'); } if (!$gridField->getList() instanceof UnsavedRelationList) { $allList = $allList->subtract($gridField->getList()); } $results = $allList->filterAny($params)->sort(strtok($searchFields[0], ':'), 'ASC')->limit($this->getResultsLimit()); $json = array(); $originalSourceFileComments = Config::inst()->get('SSViewer', 'source_file_comments'); Config::inst()->update('SSViewer', 'source_file_comments', false); foreach ($results as $result) { $json[$result->ID] = html_entity_decode(SSViewer::fromString($this->resultsFormat)->process($result)); } Config::inst()->update('SSViewer', 'source_file_comments', $originalSourceFileComments); return Convert::array2json($json); }
/** * Small helper to render templates from strings * Cloned from SSViewerTest */ private function render($templateString, $data = null) { $t = SSViewer::fromString($templateString); if (!$data) { $data = new SSViewerTestFixture(); } return $t->process($data); }
function testComments() { $viewer = SSViewer::fromString(<<<SS This is my template<%-- this is a comment --%>This is some content<%-- this is another comment --%>This is the final content SS ); $output = $viewer->process(new ArrayData(array())); $this->assertEquals("This is my templateThis is some contentThis is the final content", preg_replace("/\n?<!--.*-->\n?/U", '', $output)); }
/** * @return Array */ public function getAttributes() { $attributes = array_merge(parent::getAttributes(), array('type' => 'hidden', 'data-searchurl' => $this->Link('search'), 'data-minimuminputlength' => $this->getConfig('minimumInputLength'), 'data-resultslimit' => $this->getConfig('resultsLimit'), 'data-placeholder' => $this->getConfig('placeholder'), 'data-multiple' => $this->getConfig('multiple'))); if ($this->Value() && ($object = DataObject::get($this->getConfig('classToSearch'))->byID($this->Value()))) { $originalSourceFileComments = Config::inst()->get('SSViewer', 'source_file_comments'); Config::inst()->update('SSViewer', 'source_file_comments', false); $attributes['data-selectioncontent'] = html_entity_decode(SSViewer::fromString($this->getConfig('selectionFormat'))->process($object)); Config::inst()->update('SSViewer', 'source_file_comments', $originalSourceFileComments); } return $attributes; }
function __construct($controller, $name, $class = 'Page', $limit = 30) { Requirements::javascript(ABC_PATH . '/javascript/child-list.js'); Requirements::css(ABC_PATH . '/css/child-list.css'); $do = new DataObject(); $do->DataSet = AddPaginator::get($limit)->fetch($class, "SiteTree.ParentID = " . $controller->ID, "PublicationDate DESC, Created DESC"); $do->Paginator = $do->DataSet->Paginator->dataForTemplate(null, null, '/admin/getitem?ID=' . $controller->ID); $parser = SSViewer::fromString(SSViewer::getTemplateContent('ChildList')); $str = $parser->process($do); parent::__construct($name, $str); }
public function execute(WorkflowInstance $workflow) { $members = $workflow->getAssignedMembers(); if (!$members || !count($members)) { return true; } $member = Member::currentUser(); $initiator = $workflow->Initiator(); $contextFields = $this->getContextFields($workflow->getTarget()); $memberFields = $this->getMemberFields($member); $initiatorFields = $this->getMemberFields($initiator); $variables = array(); foreach ($contextFields as $field => $val) { $variables["\$Context.{$field}"] = $val; } foreach ($memberFields as $field => $val) { $variables["\$Member.{$field}"] = $val; } foreach ($initiatorFields as $field => $val) { $variables["\$Initiator.{$field}"] = $val; } $pastActions = $workflow->Actions()->sort('Created DESC'); $variables["\$CommentHistory"] = $this->customise(array('PastActions' => $pastActions, 'Now' => SS_Datetime::now()))->renderWith('CommentHistory'); $from = str_replace(array_keys($variables), array_values($variables), $this->EmailFrom); $subject = str_replace(array_keys($variables), array_values($variables), $this->EmailSubject); if ($this->config()->whitelist_template_variables) { $item = new ArrayData(array('Initiator' => new ArrayData($initiatorFields), 'Member' => new ArrayData($memberFields), 'Context' => new ArrayData($contextFields), 'CommentHistory' => $variables["\$CommentHistory"])); } else { $item = $workflow->customise(array('Items' => $workflow->Actions(), 'Member' => $member, 'Context' => new ArrayData($contextFields), 'CommentHistory' => $variables["\$CommentHistory"])); } if ($this->ListingTemplateID) { $template = DataObject::get_by_id('ListingTemplate', $this->ListingTemplateID); $view = SSViewer::fromString($template->ItemTemplate); } else { $view = SSViewer::fromString($this->EmailTemplate); } $body = $view->process($item); foreach ($members as $member) { if ($member->Email) { $email = new Email(); $email->setTo($member->Email); $email->setSubject($subject); $email->setFrom($from); $email->setBody($body); $email->send(); } } return true; }
public function execute(WorkflowInstance $workflow) { $email = new Email(); $members = $workflow->getAssignedMembers(); $emails = ''; if (!$members || !count($members)) { return; } foreach ($members as $member) { if ($member->Email) { $emails .= "{$member->Email}, "; } } $context = $this->getContextFields($workflow->getTarget()); $member = $this->getMemberFields(); $variables = array(); foreach ($context as $field => $val) { $variables["\$Context.{$field}"] = $val; } foreach ($member as $field => $val) { $variables["\$Member.{$field}"] = $val; } $subject = str_replace(array_keys($variables), array_values($variables), $this->EmailSubject); if ($this->ListingTemplateID) { $item = $workflow->customise(array('Items' => $workflow->Actions(), 'Member' => Member::currentUser(), 'Context' => $workflow->getTarget())); $template = DataObject::get_by_id('ListingTemplate', $this->ListingTemplateID); $view = SSViewer::fromString($template->ItemTemplate); $body = $view->process($item); } else { $body = str_replace(array_keys($variables), array_values($variables), $this->EmailTemplate); } $email->setSubject($subject); $email->setFrom($this->EmailFrom); $email->setBcc(substr($emails, 0, -2)); $email->setBody($body); $email->send(); return true; }
/** * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion * * @param GridField $gridField * @param SS_HTTPRequest $request * @return sting in JSON fromat */ public function doSearch($gridField, $request) { $dataClass = $gridField->getList()->dataClass(); $allList = $this->searchList ? $this->searchList : DataList::create($dataClass); $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass); if (!$searchFields) { throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass)); } // TODO Replace with DataList->filterAny() once it correctly supports OR connectives $stmts = array(); foreach ($searchFields as $searchField) { $stmts[] .= sprintf('"%s" LIKE \'%s%%\'', $searchField, Convert::raw2sql($request->getVar('gridfield_relationsearch'))); } $results = $allList->where(implode(' OR ', $stmts))->subtract($gridField->getList()); $results = $results->sort($searchFields[0], 'ASC'); $results = $results->limit($this->getResultsLimit()); if (!empty($this->filters)) { $results = $results->addFilter($this->filters); } if (!empty($this->excludes)) { switch (count($this->excludes)) { case 1: $key = key($this->excludes); $results->exclude($key, $this->excludes[$key]); break; case 2: $results->exclude($this->excludes); break; default: throw new InvalidArgumentException('Incorrect number of arguments passed to filter()'); } } $json = array(); foreach ($results as $result) { $json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result); } return Convert::array2json($json); }
/** * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion * * @param GridField $gridField * @param SS_HTTPRequest $request */ public function doSearch($gridField, $request) { $dataClass = $gridField->getList()->dataClass(); $allList = DataList::create($dataClass); $filters = array(); $stmts = array(); $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass); if (!$searchFields) { throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass)); } // TODO Replace with DataList->filterAny() once it correctly supports OR connectives foreach ($searchFields as $searchField) { $stmts[] .= 'LOWER(' . $searchField . ') LIKE \'%' . strtolower(Convert::raw2sql($request->getVar('gridfield_relationsearch'))) . '%\''; } $results = $allList->where(implode(' OR ', $stmts)); $results = $results->sort($searchFields[0], 'ASC'); $results = $results->limit($this->getResultsLimit()); $json = array(); foreach ($results as $result) { $json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result); } return Convert::array2json($json); }
/** * Gets the {@link FieldList} for editing the record * @return FieldList */ public function getCMSFields() { // Requirements for Ace editor Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace/ace.js'); Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace/theme-chrome.js'); Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace/mode-html.js'); Requirements::javascript(PERMAMAIL_DIR . '/javascript/jquery-ace.js'); Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace-init.js'); $fields = FieldList::create(TabSet::create("Root")); $fields->addFieldToTab('Root.Main', TextField::create('Identifier', 'Template name (no spaces, alphanumeric characters only)')); $fields->addFieldToTab('Root.Main', TextField::create('Subject', 'Default subject (optional)')); $fields->addFieldToTab('Root.Main', TextField::create('From', 'Default "from" address (optional)')); $fields->addFieldToTab('Root.Main', CheckboxField::create('IsAbstractTemplate', 'Is this an abstract template?<br>Abstract templates can be inherited by other templates. Useful for similar layout templates.')); $fields->addFieldToTab('Root.Main', DropdownField::create('ParentTemplate', 'Parent Abstract template. Useful for similar layout templates.', PermamailTemplate::get()->filter('IsAbstractTemplate', true))); $fields->addFieldToTab('Root.Main', TextareaField::create('Content', 'Template content')->addExtraClass('ace')->setRows(30)->setColumns(100)->setFieldHolderTemplate('PermamailTemplateEditor')); $vars = array(); foreach ($this->TestVariables() as $v) { $value = $v->getVariableValue(); $vars[$v->Variable] = $value ? $value : ''; } // Populate the Content field with default Content from file template try { $content = SSViewer::fromString($this->getContent()); $content = $content->process(new ViewableData(), $vars); if ($this->IsAbstractTemplate && $this->MainTemplate()->exists()) { $contentMain = SSViewer::fromString($this->MainTemplate()->getContent()); $content = $contentMain->process(new ViewableData(), array('Content' => $content)); } } catch (SSTemplateParseException $e) { $content = $e->getMessage(); } $fields->addFieldToTab('Root.Main', new LabelField('ContentOutput', '<strong>Template Output</strong><br> <div style="background-color:white; padding: 1em; border: 3px solid grey;">' . $content . '</div><br>'), 'Content'); $fields->addFieldsToTab("Root.Tests", array(EmailField::create('TestEmailAddress', 'Test email address'), GridField::create('TestVariables', 'Test variables', $this->TestVariables(), GridFieldConfig_RecordEditor::create()))); return $fields; }
/** * Replaces placeholders within the $content property their actual value * * @param string $content * * @return string */ public function replacePlaceholders($content) { // Find placeholders preg_match_all("/{{(.*?)}}/", $this->owner->Content, $matches); // If placeholders found if (!empty($matches[1])) { // Fetch view templates $templates = DataObject::get('ViewTemplate')->filter(['Title' => $matches[1]])->getIterator(); // Replace placeholders with their templates foreach ($matches[0] as $key => $templateHolder) { if ($templates->offsetExists($key)) { // Remove <p> if TinyMCE added them $content = str_replace('<p>' . $templateHolder . '</p>', $templateHolder, $content); // Process the template $template = SSViewer::fromString($templates->offsetGet($key)->ViewTemplate)->process($this->owner); // Replace the placeholder with its template $content = str_replace($templateHolder, $template, $content); } } } // Set and return content $this->owner->Content = $content; return $content; }
/** * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion * * @param GridField $gridField * @param SS_HTTPRequest $request */ public function doSearch($gridField, $request) { $dataClass = $gridField->getList()->dataClass(); $allList = $this->searchList ? $this->searchList : DataList::create($dataClass); $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass); if (!$searchFields) { throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass)); } $params = array(); foreach ($searchFields as $searchField) { $name = strpos($searchField, ':') !== FALSE ? $searchField : "{$searchField}:StartsWith"; $params[$name] = $request->getVar('gridfield_relationsearch'); } $results = $allList->subtract($gridField->getList())->filterAny($params)->sort(strtok($searchFields[0], ':'), 'ASC')->limit($this->getResultsLimit()); $json = array(); foreach ($results as $result) { $json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result); } return Convert::array2json($json); }
/** * Load all the template variables into the internal variables, including * the template into body. Called before send() or debugSend() * $isPlain=true will cause the template to be ignored, otherwise the GenericEmail template will be used * and it won't be plain email :) */ protected function parseVariables($isPlain = false) { if(!$this->parseVariables_done) { $this->parseVariables_done = true; // Parse $ variables in the base parameters $data = $this->templateData(); foreach(array('from','to','subject','body', 'plaintext_body', 'cc', 'bcc') as $param) { $template = SSViewer::fromString($this->$param); $this->$param = $template->process($data); } // Process a .SS template file $fullBody = $this->body; if($this->ss_template && !$isPlain) { // Requery data so that updated versions of To, From, Subject, etc are included $data = $this->templateData(); $template = new SSViewer($this->ss_template); if($template->exists()) { $fullBody = $template->process($data); } } // Rewrite relative URLs $this->body = HTTP::absoluteURLs($fullBody); } }
public function Content() { if (!$this->ID) { return ''; } $action = Controller::has_curr() ? Controller::curr()->getRequest()->latestParam('Action') : null; if ($this->ComponentFilterName && !$action) { // For a list of relations like tags/categories/etc $items = $this->ComponentListingItems(); $item = $this->customise(array('Items' => $items)); $view = SSViewer::fromString($this->ComponentListingTemplate()->ItemTemplate); } else { $items = $this->ListingItems(); $item = $this->customise(array('Items' => $items)); $view = SSViewer::fromString($this->ListingTemplate()->ItemTemplate); } $content = str_replace('<p>$Listing</p>', '$Listing', $this->Content); return str_replace('$Listing', $view->process($item), $content); }
/** * Return the results with a template applied to them based on the page's listing template * */ public function TemplatedResults() { $query = $this->owner->data()->getQuery(); if ($this->owner->data()->ListingTemplateID && $query) { $template = DataObject::get_by_id('ListingTemplate', $this->owner->data()->ListingTemplateID); if ($template && $template->exists()) { $items = $query ? $query->getDataObjects() : new DataObjectSet(); $item = $this->owner->data()->customise(array('Items' => $items)); $view = SSViewer::fromString($template->ItemTemplate); return $view->process($item); } } }
/** * Get string value of HTML body with all variable evaluated. * * @param SiteConfig $config * @param array List of safe template variables to expose to this template * * @return HTMLText */ protected function getEmailBody($config, $variables, $type) { if ($type == "reminder1") { $template = SSViewer::fromString($config->ReviewBodyFirstReminder); } if ($type == "reminder2") { $template = SSViewer::fromString($config->ReviewBodySecondReminder); } if ($type == "due") { $template = SSViewer::fromString($config->ReviewBody); } $value = $template->process(new ArrayData($variables)); // Cast to HTML return DBField::create_field('HTMLText', (string) $value); }
protected function getTestTemplate() { return SSViewer::fromString('A=$a, B=$b, C.E=$c.e, D.H=$d.h, E=<% loop e %>$a<% end_loop %>'); }
public function renderClusterInformationBubble($stationIDList, $extraParam = null, $templateName = '') { // multiple stations, render list $obj = new ArrayList(); $obj = $this->getFeature($stationIDList, $extraParam); foreach ($obj as $item) { $item->classname = "content_" . str_replace('.', '_', $item->FeatureID); } $data = new ArrayData(array("items" => $obj, "count" => $obj->Count())); if ($this->UseTemplateForPopupWindow) { $template = $this->Popup_ClusterInformation; $viewer = SSViewer::fromString($template); return $viewer->process($data); } // @to2: deprecate this $listItemTemplate = 'Station: $FeatureID'; if ($this->ClusterAttributes) { $listItemTemplate = $this->ClusterAttributes; } // 1st partial template: create template for content area $template = '<% loop items %>'; $template .= sprintf('<li><a onClick="multipleStationSelect(\'$FeatureID\');return false;">%s</a></li><div class=\'$classname\'></div>', $listItemTemplate); $template .= '<% end_loop %>'; // 2nd partial template: create template for header area $header = 'There are $count Items.'; if ($this->ClusterPopupHeader) { $header = $this->ClusterPopupHeader; } // render partial tempates $viewer = SSViewer::fromString($header); $clusterPopupHeader = $viewer->process($data); $viewer = SSViewer::fromString($template); $stationListTemplate = $viewer->process($data); // render combined tempate $out = new ViewableData(); $out->customise(array("stationList" => $stationListTemplate, "PopupHeader" => $clusterPopupHeader)); return $out->renderWith('MapPopup_List'); }
public function RequireCustomTemplatedJS($template) { $template = str_replace('<script>', '', $template); $template = str_replace('</script>', '', $template); $template = SSViewer::fromString($template); $result = $template->process($this->owner); Requirements::customScript($result); }
function notifyError($type, $fields = null) { list($subject, $body) = self::$errors[$type]; $subject = self::$error_email_subject_prefix . $subject; $body = self::$error_email_body_prefix . $body . self::$error_email_body_suffix; if ($fields) { if (!is_array($fields)) { $fields = array($fields); } $this->owner->AndFieldNames = implode(' and ', $fields); $this->owner->OrFieldNames = "'" . implode("' or '", $fields) . "'"; } $parser = SSViewer::fromString($subject); $subject = $parser->process($this->owner); $parser = SSViewer::fromString($body); $body = $parser->process($this->owner); $from = self::$error_email_from; if (!$from) { $from = Email::getAdminEmail(); } $to = self::$error_email_to; if (!$to) { $to = Email::getAdminEmail(); } $email = new Email($from, $to, $subject, $body); $email->send(); }
public function Content() { $items = $this->ListingItems(); $item = $this->customise(array('Items' => $items)); $view = SSViewer::fromString($this->ListingTemplate()->ItemTemplate); $content = str_replace('<p>$Listing</p>', '$Listing', $this->Content); return str_replace('$Listing', $view->process($item), $content); }
/** * Gets called recursively on the child-objects of the chain. * * @param array $nestingLevels see {@buildNestedUL} * @param int $level Current nesting level * @param string $template Template for list item * @param string $ulExtraAttributes Extra attributes * @return string */ public function getChildrenAsUL($nestingLevels, $level = 0, $template = "<li id=\"record-\$ID\" class=\"\$EvenOdd\">\$Title", $ulExtraAttributes = null, &$itemCount = 0) { $output = ""; $hasNextLevel = false; $ulExtraAttributes = " $ulExtraAttributes"; $output = "<ul" . eval($ulExtraAttributes) . ">\n"; $currentNestingLevel = $nestingLevels[$level]; // either current or default template $currentTemplate = (!empty($currentNestingLevel)) ? $currentNestingLevel['template'] : $template; $myViewer = SSViewer::fromString($currentTemplate); if(isset($nestingLevels[$level+1]['dataclass'])){ $childrenMethod = $nestingLevels[$level+1]['dataclass']; } // sql-parts $filter = (isset($nestingLevels[$level+1]['filter'])) ? $nestingLevels[$level+1]['filter'] : null; $sort = (isset($nestingLevels[$level+1]['sort'])) ? $nestingLevels[$level+1]['sort'] : null; $join = (isset($nestingLevels[$level+1]['join'])) ? $nestingLevels[$level+1]['join'] : null; $limit = (isset($nestingLevels[$level+1]['limit'])) ? $nestingLevels[$level+1]['limit'] : null; $having = (isset($nestingLevels[$level+1]['having'])) ? $nestingLevels[$level+1]['having'] : null; foreach($this as $parent) { $evenOdd = ($itemCount % 2 == 0) ? "even" : "odd"; $parent->setField('EvenOdd', $evenOdd); $template = $myViewer->process($parent); // if no output is selected, fall back to the id to keep the item "clickable" $output .= $template . "\n"; if(isset($childrenMethod)) { // workaround for missing groupby/having-parameters in instance_get // get the dataobjects for the next level $children = $parent->$childrenMethod($filter, $sort, $join, $limit, $having); if($children) { $output .= $children->getChildrenAsUL($nestingLevels, $level+1, $currentTemplate, $ulExtraAttributes); } } $output .= "</li>\n"; $itemCount++; } $output .= "</ul>\n"; return $output; }
/** * Process and render search results (taken from @Link ContentControllerSearchExtension with slightly altered parameters). * * @param array $data The raw request data submitted by user * @param SearchForm $form The form instance that was submitted */ public function getSearchResults($data = null, $form = null) { // Keep track of the search time taken. $startTime = microtime(true); // Don't allow searching without a valid search engine. $engine = $this->data()->SearchEngine; $fulltext = Config::inst()->get('FulltextSearchable', 'searchable_classes'); if (is_null($engine) || $engine === 'Full-Text' && (!is_array($fulltext) || count($fulltext) === 0)) { return $this->httpError(404); } // Attempt to retrieve the results for the current search engine extension. if ($engine !== 'Full-Text' && $this->extension_instances) { $extension = "{$engine}Search_Controller"; foreach ($this->extension_instances as $instance) { if (get_class($instance) === $extension) { $instance->setOwner($this); if (method_exists($instance, 'getSearchResults')) { // Keep track of the search time taken, for the current search engine extension. $startTime = microtime(true); $customisation = $instance->getSearchResults($data, $form); $output = $this->customise($customisation)->renderWith(array("{$engine}Search_results", "{$engine}SearchPage_results", 'ExtensibleSearch_results', 'ExtensibleSearchPage_results', 'Page_results', "{$engine}Search", "{$engine}SearchPage", 'ExtensibleSearch', 'ExtensibleSearchPage', 'Page')); $totalTime = microtime(true) - $startTime; // Log the details of a user search for analytics. $this->service->logSearch($data['Search'], isset($customisation['Results']) && ($results = $customisation['Results']) ? count($results) : 0, $totalTime, $engine, $this->data()->ID); return $output; } $instance->clearOwner(); break; } } } // Fall back to displaying the full-text results. $searchable = Config::inst()->get('FulltextSearchable', 'searchable_classes'); if (is_null($sort = $this->data()->SortBy)) { $sort = 'Relevance'; } $direction = $this->data()->SortDir === 'Ascending' ? 'ASC' : 'DESC'; // Apply any site tree restrictions. $filter = implode(', ', $this->SearchTrees()->map('ID', 'ID')->toArray()); if ($filter) { $filter = "ParentID IN({$filter})"; } $results = is_array($searchable) && count($searchable) > 0 && $form ? $form->getExtendedResults($this->data()->ResultsPerPage, "{$sort} {$direction}", $filter, $data) : null; // Render the full-text results using a listing template where defined. if ($this->data()->ListingTemplateID && $results) { $template = DataObject::get_by_id('ListingTemplate', $this->data()->ListingTemplateID); if ($template && $template->exists()) { $render = $this->data()->customise(array('Items' => $results)); $viewer = SSViewer::fromString($template->ItemTemplate); $results = $viewer->process($render); } } // Render everything into the search page template. $customisation = array('Results' => $results, 'Query' => $form ? $form->getSearchQuery() : null, 'Title' => _t('ExtensibleSearchPage.SearchResults', 'Search Results')); $output = $this->customise($customisation)->renderWith(array('ExtensibleSearch_results', 'ExtensibleSearchPage_results', 'Page_results', 'ExtensibleSearch', 'ExtensibleSearchPage', 'Page')); $totalTime = microtime(true) - $startTime; // Log the details of a user search for analytics. $this->service->logSearch($data['Search'], $results ? count($results) : 0, $totalTime, $engine, $this->data()->ID); return $output; }
/** * See {@link ViewableDataTest} for more extensive casting tests, * this test just ensures that basic casting is correctly applied during template parsing. */ public function testCastingHelpers() { $vd = new SSViewerTest_ViewableData(); $vd->TextValue = '<b>html</b>'; $vd->HTMLValue = '<b>html</b>'; $vd->UncastedValue = '<b>html</b>'; // Value casted as "Text" $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$TextValue')->process($vd)); $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$TextValue.RAW')->process($vd)); $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$TextValue.XML')->process($vd)); // Value casted as "HTMLText" $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$HTMLValue')->process($vd)); $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$HTMLValue.RAW')->process($vd)); $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$HTMLValue.XML')->process($vd)); // Uncasted value (falls back to ViewableData::$default_cast="HTMLText") $vd = new SSViewerTest_ViewableData(); // TODO Fix caching $vd->UncastedValue = '<b>html</b>'; $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$UncastedValue')->process($vd)); $vd = new SSViewerTest_ViewableData(); // TODO Fix caching $vd->UncastedValue = '<b>html</b>'; $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$UncastedValue.RAW')->process($vd)); $vd = new SSViewerTest_ViewableData(); // TODO Fix caching $vd->UncastedValue = '<b>html</b>'; $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$UncastedValue.XML')->process($vd)); }
/** * Returns a json array of a search results that can be used by for * example Jquery.ui.autosuggestion * * @param GridField $gridField * @param SS_HTTPRequest $request */ public function doSearch($gridField, $request) { $product_class = $this->getSourceClass(); $params = array(); // Do we have filter fields setup? if ($this->getAutocompleteFields()) { $search_fields = $this->getAutocompleteFields(); } else { $search_fields = $this->scaffoldSearchFields($product_class); } if (!$search_fields) { throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $product_class)); } foreach ($search_fields as $search_field) { $name = strpos($search_field, ':') !== false ? $search_field : "{$search_field}:StartsWith"; $params[$name] = $request->getVar('gridfieldaddbydbfield'); } $results = DataList::create($product_class)->filterAny($params)->sort(strtok($search_fields[0], ':'), 'ASC')->limit($this->getResultsLimit()); $json = array(); $originalSourceFileComments = Config::inst()->get('SSViewer', 'source_file_comments'); Config::inst()->update('SSViewer', 'source_file_comments', false); foreach ($results as $result) { $json[$result->ID] = html_entity_decode(SSViewer::fromString($this->results_format)->process($result)); } Config::inst()->update('SSViewer', 'source_file_comments', $originalSourceFileComments); return Convert::array2json($json); }
/** * Process an SS template as string so that it can access $EditableTextField_6746f values */ public function processTemplateMarkup($ssMarkup, $data = array()) { $submission = $this->owner->Submission(); if (!$submission || !$submission->exists()) { return null; } $data = array('Values' => $submission->Values()); foreach ($submission->Values() as $record) { $data[$record->Name] = $record->getFormattedValue(); } return DBField::create_field('HTMLText', SSViewer::fromString($ssMarkup)->process($this->owner->customise($data))); }
function testBaseTagGeneration() { // XHTML wil have a closed base tag $tmpl1 = SSViewer::fromString('<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head><% base_tag %></head> <body><p>test</p><body> </html>'); $this->assertRegExp('/<head><base href=".*" \\/><\\/head>/', $tmpl1->process(new ViewableData())); // HTML4 and 5 will only have it for IE $tmpl2 = SSViewer::fromString('<!DOCTYPE html> <html> <head><% base_tag %></head> <body><p>test</p><body> </html>'); $this->assertRegExp('/<head><base href=".*"><!--\\[if lte IE 6\\]><\\/base><!\\[endif\\]--><\\/head>/', $tmpl2->process(new ViewableData())); $tmpl3 = SSViewer::fromString('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head><% base_tag %></head> <body><p>test</p><body> </html>'); $this->assertRegExp('/<head><base href=".*"><!--\\[if lte IE 6\\]><\\/base><!\\[endif\\]--><\\/head>/', $tmpl3->process(new ViewableData())); // Check that the content negotiator converts to the equally legal formats $negotiator = new ContentNegotiator(); $response = new SS_HTTPResponse($tmpl1->process(new ViewableData())); $negotiator->html($response); $this->assertRegExp('/<head><base href=".*"><!--\\[if lte IE 6\\]><\\/base><!\\[endif\\]--><\\/head>/', $response->getBody()); $response = new SS_HTTPResponse($tmpl1->process(new ViewableData())); $negotiator->xhtml($response); $this->assertRegExp('/<head><base href=".*" \\/><\\/head>/', $response->getBody()); }
/** * Execute the evaluated string, passing it the given data. * Used by partial caching to evaluate custom cache keys expressed using * template expressions * * @param string $content Input string * @param mixed $data Data context * @param array $arguments Additional arguments * @return string Evaluated result */ public static function execute_string($content, $data, $arguments = null) { $v = SSViewer::fromString($content); $v->includeRequirements(false); return $v->process($data, $arguments); }
/** * Overload the Email::parseVariables() method to use a user-defined template * @param boolean $isPlain * @return Permamail */ public function parseVariables($isPlain = false) { $origState = Config::inst()->get('SSViewer', 'source_file_comments'); Config::inst()->update('SSViewer', 'source_file_comments', false); $userTemplate = $this->getUserTemplate(); if (!$this->parseVariables_done) { $this->parseVariables_done = true; // Parse $ variables in the base parameters $data = $this->templateData(); // Process a .SS template file $fullBody = $this->body; if ($userTemplate || $this->ss_template && !$isPlain) { // Requery data so that updated versions of To, From, Subject, etc are included $data = $this->templateData(); $template = $userTemplate ? SSViewer::fromString($userTemplate->Content) : new SSViewer($this->ss_template); if ($template instanceof SSViewer_FromString || $template->exists()) { $fullBody = $template->process($data); } } // Rewrite relative URLs $this->body = HTTP::absoluteURLs($fullBody); } Config::inst()->update('SSViewer', 'source_file_comments', $origState); return $this; }