public function testVersionedCache()
 {
     $origReadingMode = Versioned::get_reading_mode();
     // Run without caching in stage to prove data is uncached
     $this->_reset(false);
     Versioned::set_stage(Versioned::DRAFT);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('default');
     $this->assertEquals('default Stage.Stage', SSViewer::execute_string('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('first Stage.Stage', SSViewer::execute_string('<% cached %>$Inspect<% end_cached %>', $data));
     // Run without caching in live to prove data is uncached
     $this->_reset(false);
     Versioned::set_stage(Versioned::LIVE);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('default');
     $this->assertEquals('default Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('first Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     // Then with caching, initially in draft, and then in live, to prove that
     // changing the versioned reading mode doesn't cache between modes, but it does
     // within them
     $this->_reset(true);
     Versioned::set_stage(Versioned::DRAFT);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('default');
     $this->assertEquals('default Stage.Stage', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('default Stage.Stage', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     Versioned::set_stage(Versioned::LIVE);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('first Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('second');
     $this->assertEquals('first Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     Versioned::set_reading_mode($origReadingMode);
 }
 public function setUp()
 {
     parent::setUp();
     Director::config()->update('rules', array('FormTest_Controller' => 'FormTest_Controller'));
     // Suppress themes
     SSViewer::config()->remove('theme');
 }
 public function getHTMLFragments($gridField)
 {
     $count = $gridField->getList()->count();
     $forTemplate = new ArrayData(array('ShowRecordCount' => $this->showrecordcount, 'Message' => $this->message, 'FirstShownRecord' => 1, 'LastShownRecord' => $count, 'NumRecords' => $count));
     $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array('footer' => $forTemplate->renderWith($template, array('Colspan' => count($gridField->getColumns()))));
 }
 /**
  * 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);
 }
 public function getColumnContent($field, $record, $col)
 {
     if (!$record->canView()) {
         return null;
     }
     $data = new ArrayData(array('Link' => Controller::join_links($field->Link('item'), $record->ID, 'view')));
     $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return $data->renderWith($template);
 }
 /**
  * @param GridField $gridField
  * @return array
  */
 public function getHTMLFragments($gridField)
 {
     // Retrieve paging parameters from the directing paginator component
     $paginator = $this->getPaginator($gridField);
     if ($paginator && ($forTemplate = $paginator->getTemplateParameters($gridField))) {
         $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
         return array($this->targetFragment => $forTemplate->renderWith($template));
     }
     return null;
 }
 public function getHTMLFragments($gridField)
 {
     $singleton = singleton($gridField->getModelClass());
     if (!$singleton->canCreate()) {
         return array();
     }
     if (!$this->buttonName) {
         // provide a default button name, can be changed by calling {@link setButtonName()} on this component
         $objectName = $singleton->i18n_singular_name();
         $this->buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName));
     }
     $data = new ArrayData(array('NewLink' => Controller::join_links($gridField->Link('item'), 'new'), 'ButtonName' => $this->buttonName));
     $templates = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array($this->targetFragment => $data->renderWith($templates));
 }
 public function setUp()
 {
     // Skip calling FunctionalTest directly.
     if (get_class($this) == __CLASS__) {
         $this->markTestSkipped(sprintf('Skipping %s ', get_class($this)));
     }
     parent::setUp();
     $this->mainSession = new TestSession();
     // Disable theme, if necessary
     if (static::get_disable_themes()) {
         SSViewer::config()->update('theme_enabled', false);
     }
     // Switch to draft site, if necessary
     if (static::get_use_draft_site()) {
         $this->useDraftSite();
     }
     // Unprotect the site, tests are running with the assumption it's off. They will enable it on a case-by-case
     // basis.
     BasicAuth::protect_entire_site(false);
     SecurityToken::disable();
 }
 public function getHTMLFragments($gridField)
 {
     $modelClass = $gridField->getModelClass();
     $parentID = 0;
     if (!$this->currentID) {
         return null;
     }
     $modelObj = DataObject::get_by_id($modelClass, $this->currentID);
     $parent = null;
     if ($modelObj->hasMethod('getParent')) {
         $parent = $modelObj->getParent();
     } elseif ($modelObj->ParentID) {
         $parent = $modelObj->Parent();
     }
     if ($parent) {
         $parentID = $parent->ID;
     }
     // Attributes
     $attrs = array_merge($this->attributes, array('href' => sprintf($this->linkSpec, $parentID), 'class' => 'cms-panel-link ss-ui-button font-icon-level-up no-text grid-levelup'));
     $linkTag = FormField::create_tag('a', $attrs);
     $forTemplate = new ArrayData(array('UpLink' => DBField::create_field('HTMLFragment', $linkTag)));
     $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array('before' => $forTemplate->renderWith($template));
 }
 /**
  * Test against a theme.
  *
  * @param string $themeBaseDir themes directory
  * @param string $theme Theme name
  * @param callable $callback
  * @throws Exception
  */
 protected function useTestTheme($themeBaseDir, $theme, $callback)
 {
     Config::nest();
     if (strpos($themeBaseDir, BASE_PATH) === 0) {
         $themeBaseDir = substr($themeBaseDir, strlen(BASE_PATH));
     }
     SSViewer::config()->update('theme_enabled', true);
     SSViewer::set_themes([$themeBaseDir . '/themes/' . $theme, '$default']);
     $e = null;
     try {
         $callback();
     } catch (Exception $e) {
         /* NOP for now, just save $e */
     }
     Config::unnest();
     if ($e) {
         throw $e;
     }
 }
 function CacheBlock_CacheBlockTemplate(&$res, $sub)
 {
     // Get the block counter
     $block = ++$res['subblocks'];
     // Build the key for this block from the global key (evaluated in a closure within the template),
     // the passed cache key, the block index, and the sha hash of the template.
     $res['php'] .= '$keyExpression = function() use ($scope, $cache) {' . PHP_EOL;
     $res['php'] .= '$val = \'\';' . PHP_EOL;
     if ($globalKey = SSViewer::config()->get('global_key')) {
         // Embed the code necessary to evaluate the globalKey directly into the template,
         // so that SSTemplateParser only needs to be called during template regeneration.
         // Warning: If the global key is changed, it's necessary to flush the template cache.
         $parser = Injector::inst()->get(__CLASS__, false);
         $result = $parser->compileString($globalKey, '', false, false);
         if (!$result) {
             throw new SSTemplateParseException('Unexpected problem parsing template', $parser);
         }
         $res['php'] .= $result . PHP_EOL;
     }
     $res['php'] .= 'return $val;' . PHP_EOL;
     $res['php'] .= '};' . PHP_EOL;
     $key = 'sha1($keyExpression())' . '.\'_' . sha1($sub['php']) . (isset($res['key']) && $res['key'] ? "_'.sha1(" . $res['key'] . ")" : "'") . ".'_{$block}'";
     // block index
     // Get any condition
     $condition = isset($res['condition']) ? $res['condition'] : '';
     $res['php'] .= 'if (' . $condition . '($partial = $cache->load(' . $key . '))) $val .= $partial;' . PHP_EOL;
     $res['php'] .= 'else { $oldval = $val; $val = "";' . PHP_EOL;
     $res['php'] .= $sub['php'] . PHP_EOL;
     $res['php'] .= $condition . ' $cache->save($val); $val = $oldval . $val;' . PHP_EOL;
     $res['php'] .= '}';
 }
 /**
  * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion
  *
  * @param GridField $gridField
  * @param HTTPRequest $request
  * @return string
  */
 public function doSearch($gridField, $request)
 {
     $dataClass = $gridField->getModelClass();
     $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();
     Config::nest();
     SSViewer::config()->update('source_file_comments', false);
     $viewer = SSViewer::fromString($this->resultsFormat);
     foreach ($results as $result) {
         $title = html_entity_decode($viewer->process($result));
         $json[] = array('label' => $title, 'value' => $title, 'id' => $result->ID);
     }
     Config::unnest();
     return Convert::array2json($json);
 }
 /**
  * @param GridField $gridField
  * @param DataObject $record
  * @param string $columnName
  * @return string The HTML for the column
  */
 public function getColumnContent($gridField, $record, $columnName)
 {
     // No permission checks, handled through GridFieldDetailForm,
     // which can make the form readonly if no edit permissions are available.
     $data = new ArrayData(array('Link' => Controller::join_links($gridField->Link('item'), $record->ID, 'edit')));
     $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return $data->renderWith($template);
 }
 /**
  * Render this object into the template, and get the result as a string. You can pass one of the following as the
  * $template parameter:
  *  - a template name (e.g. Page)
  *  - an array of possible template names - the first valid one will be used
  *  - an SSViewer instance
  *
  * @param string|array|SSViewer $template the template to render into
  * @param array $customFields fields to customise() the object with before rendering
  * @return DBHTMLText
  */
 public function renderWith($template, $customFields = null)
 {
     if (!is_object($template)) {
         $template = new SSViewer($template);
     }
     $data = $this->customisedObject ? $this->customisedObject : $this;
     if ($customFields instanceof ViewableData) {
         $data = $data->customise($customFields);
     }
     if ($template instanceof SSViewer) {
         return $template->process($data, is_array($customFields) ? $customFields : null);
     }
     throw new UnexpectedValueException("ViewableData::renderWith(): unexpected " . get_class($template) . " object, expected an SSViewer instance");
 }
 /**
  * Render this form using the given template, and return the result as a string
  * You can pass either an SSViewer or a template name
  * @param string|array $template
  * @return DBHTMLText
  */
 public function renderWithoutActionButton($template)
 {
     $custom = $this->customise(array("Actions" => ""));
     if (is_string($template)) {
         $template = new SSViewer($template);
     }
     return $template->process($custom);
 }
 /**
  * Generate an array of class name strings to use for rendering this form field into HTML.
  *
  * @param string $customTemplate
  * @param string $customTemplateSuffix
  *
  * @return array
  */
 protected function _templates($customTemplate = null, $customTemplateSuffix = null)
 {
     $templates = SSViewer::get_templates_by_class(get_class($this), $customTemplateSuffix, __CLASS__);
     // Prefer any custom template
     if ($customTemplate) {
         // Prioritise direct template
         array_unshift($templates, $customTemplate);
     }
     return $templates;
 }
 /**
  * @return string
  */
 public function getTemplateViewFile()
 {
     return SSViewer::get_templates_by_class(get_class($this), '_viewfile', __CLASS__);
 }
 /**
  * Get list of templates to use
  *
  * @return array
  */
 public function getTemplates()
 {
     $templates = SSViewer::get_templates_by_class($this, '', __CLASS__);
     // Prefer any custom template
     if ($this->getTemplate()) {
         array_unshift($templates, $this->getTemplate());
     }
     return $templates;
 }
 public function testRequireCallInTemplateInclude()
 {
     //TODO undo skip test on the event that templates ever obtain the ability to reference MODULE_DIR (or something to that effect)
     if (FRAMEWORK_DIR === 'framework') {
         $template = new SSViewer(array('SSViewerTestProcess'));
         Requirements::set_suffix_requirements(false);
         $this->assertEquals(1, substr_count($template->process(array()), "tests/javascript/forms/RequirementsTest_a.js"));
     } else {
         $this->markTestSkipped('Requirement will always fail if the framework dir is not ' . 'named \'framework\', since templates require hard coded paths');
     }
 }
 /**
  * Return a {@link FieldList} of fields that would appropriate for editing
  * this member.
  *
  * @return FieldList Return a FieldList of fields that would appropriate for
  *                   editing this member.
  */
 public function getCMSFields()
 {
     require_once 'Zend/Date.php';
     $self = $this;
     $this->beforeUpdateCMSFields(function (FieldList $fields) use($self) {
         /** @var FieldList $mainFields */
         $mainFields = $fields->fieldByName("Root")->fieldByName("Main")->getChildren();
         // Build change password field
         $mainFields->replaceField('Password', $self->getMemberPasswordField());
         $mainFields->replaceField('Locale', new DropdownField("Locale", _t('Member.INTERFACELANG', "Interface Language", 'Language of the CMS'), i18n::get_existing_translations()));
         $mainFields->removeByName($self->config()->hidden_fields);
         if (!$self->config()->lock_out_after_incorrect_logins) {
             $mainFields->removeByName('FailedLoginCount');
         }
         // Groups relation will get us into logical conflicts because
         // Members are displayed within  group edit form in SecurityAdmin
         $fields->removeByName('Groups');
         // Members shouldn't be able to directly view/edit logged passwords
         $fields->removeByName('LoggedPasswords');
         $fields->removeByName('RememberLoginHashes');
         if (Permission::check('EDIT_PERMISSIONS')) {
             $groupsMap = array();
             foreach (Group::get() as $group) {
                 // Listboxfield values are escaped, use ASCII char instead of &raquo;
                 $groupsMap[$group->ID] = $group->getBreadcrumbs(' > ');
             }
             asort($groupsMap);
             $fields->addFieldToTab('Root.Main', ListboxField::create('DirectGroups', singleton('SilverStripe\\Security\\Group')->i18n_plural_name())->setSource($groupsMap)->setAttribute('data-placeholder', _t('Member.ADDGROUP', 'Add group', 'Placeholder text for a dropdown')));
             // Add permission field (readonly to avoid complicated group assignment logic).
             // This should only be available for existing records, as new records start
             // with no permissions until they have a group assignment anyway.
             if ($self->ID) {
                 $permissionsField = new PermissionCheckboxSetField_Readonly('Permissions', false, 'SilverStripe\\Security\\Permission', 'GroupID', $self->getManyManyComponents('Groups'));
                 $fields->findOrMakeTab('Root.Permissions', singleton('SilverStripe\\Security\\Permission')->i18n_plural_name());
                 $fields->addFieldToTab('Root.Permissions', $permissionsField);
             }
         }
         $permissionsTab = $fields->fieldByName("Root")->fieldByName('Permissions');
         if ($permissionsTab) {
             $permissionsTab->addExtraClass('readonly');
         }
         $defaultDateFormat = Zend_Locale_Format::getDateFormat(new Zend_Locale($self->Locale));
         $dateFormatMap = array('MMM d, yyyy' => Zend_Date::now()->toString('MMM d, yyyy'), 'yyyy/MM/dd' => Zend_Date::now()->toString('yyyy/MM/dd'), 'MM/dd/yyyy' => Zend_Date::now()->toString('MM/dd/yyyy'), 'dd/MM/yyyy' => Zend_Date::now()->toString('dd/MM/yyyy'));
         $dateFormatMap[$defaultDateFormat] = Zend_Date::now()->toString($defaultDateFormat) . sprintf(' (%s)', _t('Member.DefaultDateTime', 'default'));
         $mainFields->push($dateFormatField = new MemberDatetimeOptionsetField('DateFormat', $self->fieldLabel('DateFormat'), $dateFormatMap));
         $formatClass = get_class($dateFormatField);
         $dateFormatField->setValue($self->DateFormat);
         $dateTemplate = SSViewer::get_templates_by_class($formatClass, '_description_date', $formatClass);
         $dateFormatField->setDescriptionTemplate($dateTemplate);
         $defaultTimeFormat = Zend_Locale_Format::getTimeFormat(new Zend_Locale($self->Locale));
         $timeFormatMap = array('h:mm a' => Zend_Date::now()->toString('h:mm a'), 'H:mm' => Zend_Date::now()->toString('H:mm'));
         $timeFormatMap[$defaultTimeFormat] = Zend_Date::now()->toString($defaultTimeFormat) . sprintf(' (%s)', _t('Member.DefaultDateTime', 'default'));
         $mainFields->push($timeFormatField = new MemberDatetimeOptionsetField('TimeFormat', $self->fieldLabel('TimeFormat'), $timeFormatMap));
         $timeFormatField->setValue($self->TimeFormat);
         $timeTemplate = SSViewer::get_templates_by_class($formatClass, '_description_time', $formatClass);
         $timeFormatField->setDescriptionTemplate($timeTemplate);
     });
     return parent::getCMSFields();
 }
 /**
  * Get location of all editor.css files
  *
  * @return array
  */
 protected function getEditorCSS()
 {
     $editor = array();
     // Add standard editor.css
     $editor[] = Director::absoluteURL(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/editor.css');
     // Themed editor.css
     $themedEditor = ThemeResourceLoader::instance()->findThemedCSS('editor', SSViewer::get_themes());
     if ($themedEditor) {
         $editor[] = Director::absoluteURL($themedEditor, Director::BASE);
     }
     return $editor;
 }
 /**
  * Returns TRUE if this controller has a template that is specifically designed to handle a
  * specific action.
  *
  * @param string $action
  *
  * @return bool
  */
 public function hasActionTemplate($action)
 {
     if (isset($this->templates[$action])) {
         return true;
     }
     $parentClass = $this->class;
     $templates = array();
     while ($parentClass != __CLASS__) {
         $templates[] = strtok($parentClass, '_') . '_' . $action;
         $parentClass = get_parent_class($parentClass);
     }
     return SSViewer::hasTemplate($templates);
 }
 /**
  * Renders a panel containing tools which apply to the currently displayed edit form.
  * The main difference to {@link Tools()} is that the panel is displayed within
  * the element structure of the form panel (rendered through {@link EditForm}).
  * This means the panel will be loaded alongside new forms, and refreshed upon save,
  * which can mean a performance hit, depending on how complex your panel logic gets.
  * Any form fields contained in the returned markup will also be submitted with the main form,
  * which might be desired depending on the implementation details.
  *
  * @return String HTML
  */
 public function EditFormTools()
 {
     $templates = $this->getTemplatesWithSuffix('_EditFormTools');
     if ($templates) {
         $viewer = new SSViewer($templates);
         return $viewer->process($this);
     } else {
         return false;
     }
 }
 /**
  * @param GridField $gridField
  * @return array
  */
 public function getHTMLFragments($gridField)
 {
     $templates = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array('header' => $gridField->renderWith($templates));
 }
 /**
  * Returns the header row providing titles with sort buttons
  *
  * @param GridField $gridField
  * @return array
  */
 public function getHTMLFragments($gridField)
 {
     $list = $gridField->getList();
     if (!$this->checkDataType($list)) {
         return null;
     }
     /** @var Sortable $list */
     $forTemplate = new ArrayData(array());
     $forTemplate->Fields = new ArrayList();
     $state = $gridField->State->GridFieldSortableHeader;
     $columns = $gridField->getColumns();
     $currentColumn = 0;
     $schema = DataObject::getSchema();
     foreach ($columns as $columnField) {
         $currentColumn++;
         $metadata = $gridField->getColumnMetadata($columnField);
         $fieldName = str_replace('.', '-', $columnField);
         $title = $metadata['title'];
         if (isset($this->fieldSorting[$columnField]) && $this->fieldSorting[$columnField]) {
             $columnField = $this->fieldSorting[$columnField];
         }
         $allowSort = $title && $list->canSortBy($columnField);
         if (!$allowSort && strpos($columnField, '.') !== false) {
             // we have a relation column with dot notation
             // @see DataObject::relField for approximation
             $parts = explode('.', $columnField);
             $tmpItem = singleton($list->dataClass());
             for ($idx = 0; $idx < sizeof($parts); $idx++) {
                 $methodName = $parts[$idx];
                 if ($tmpItem instanceof SS_List) {
                     // It's impossible to sort on a HasManyList/ManyManyList
                     break;
                 } elseif (method_exists($tmpItem, 'hasMethod') && $tmpItem->hasMethod($methodName)) {
                     // The part is a relation name, so get the object/list from it
                     $tmpItem = $tmpItem->{$methodName}();
                 } elseif ($tmpItem instanceof DataObject && $schema->fieldSpec($tmpItem, $methodName, DataObjectSchema::DB_ONLY)) {
                     // Else, if we've found a database field at the end of the chain, we can sort on it.
                     // If a method is applied further to this field (E.g. 'Cost.Currency') then don't try to sort.
                     $allowSort = $idx === sizeof($parts) - 1;
                     break;
                 } else {
                     // If neither method nor field, then unable to sort
                     break;
                 }
             }
         }
         if ($allowSort) {
             $dir = 'asc';
             if ($state->SortColumn(null) == $columnField && $state->SortDirection('asc') == 'asc') {
                 $dir = 'desc';
             }
             $field = GridField_FormAction::create($gridField, 'SetOrder' . $fieldName, $title, "sort{$dir}", array('SortColumn' => $columnField))->addExtraClass('grid-field__sort');
             if ($state->SortColumn(null) == $columnField) {
                 $field->addExtraClass('ss-gridfield-sorted');
                 if ($state->SortDirection('asc') == 'asc') {
                     $field->addExtraClass('ss-gridfield-sorted-asc');
                 } else {
                     $field->addExtraClass('ss-gridfield-sorted-desc');
                 }
             }
         } else {
             if ($currentColumn == count($columns) && $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldFilterHeader')) {
                 $field = new LiteralField($fieldName, '<button type="button" name="showFilter" class="btn font-icon-search btn--no-text btn--icon-large grid-field__filter-open"></button>');
             } else {
                 $field = new LiteralField($fieldName, '<span class="non-sortable">' . $title . '</span>');
             }
         }
         $forTemplate->Fields->push($field);
     }
     $template = SSViewer::get_templates_by_class($this, '_Row', __CLASS__);
     return array('header' => $forTemplate->renderWith($template));
 }
 /**
  *
  * @param GridField $gridField
  * @return array
  */
 public function getHTMLFragments($gridField)
 {
     $forTemplate = $this->getTemplateParameters($gridField);
     if (!$forTemplate) {
         return null;
     }
     $template = SSViewer::get_templates_by_class($this, '_Row', __CLASS__);
     return array('footer' => $forTemplate->renderWith($template, array('Colspan' => count($gridField->getColumns()))));
 }
 /**
  * Determine the list of templates to use for rendering the given action.
  *
  * @skipUpgrade
  * @param string $action
  * @return array Template list
  */
 public function getTemplatesFor($action)
 {
     $templates = SSViewer::get_templates_by_class(get_class($this), "_{$action}", __CLASS__);
     return array_merge($templates, ["Security_{$action}", "Security", $this->stat("template_main"), "BlankPage"]);
 }
 public function getHTMLFragments($gridField)
 {
     $data = new ArrayData(array("TargetFragmentName" => $this->targetFragment, "LeftFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-left)", "RightFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-right)"));
     $templates = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array($this->targetFragment => $data->renderWith($templates));
 }
 public function parseTemplateContent($content, $template = "")
 {
     return $this->getParser()->compileString($content, $template, Director::isDev() && SSViewer::config()->get('source_file_comments'));
 }
 public function showform()
 {
     return "<head>" . SSViewer::get_base_tag("") . "</head>" . $this->Form()->forTemplate();
 }