I can't seem to change the templates that the results function uses. I've taken the results function and modified the template but it's rendering with Page.ss instead of MyCustomResultTemplate.ss
public function results($data, $form, $request)
{
// [...]
$templates = array(
'MyCustomResultTemplate',
'Page'
);
return $this->owner->customise($data)->renderWith($templates);
}
MyCustomResultTemplate.ss exists in the correct templates folder and looks identical the the default Page_results.ss file yet still no luck.
Am I missing some route setting or something here?
Related
I want to create a CakePHP Widget in order to create a custom form control. The end goal is to make it a plugin, but for now I am trying to determine the general structure of a Widget. I have created a file in src/View/Widget/DateTimeWidget.php containing
<?php
namespace App\View\Widget;
use Cake\View\Form\ContextInterface;
use Cake\View\Widget\WidgetInterface;
class DateTimeWidget implements WidgetInterface
{
protected $_templates;
public function __construct($templates)
{
$this->_templates = $templates;
}
public function render(array $data, ContextInterface $context)
{
$data += [
'name' => '',
];
return $this->_templates->format('DateTime', [
'name' => $data['name'],
'attrs' => $this->_templates->formatAttributes($data, ['name'])
]);
}
public function secureFields(array $data)
{
return [$data['name']];
}
}
?>
I load the Widget in a View with the code
$this->Form->addWidget(
'datetime',
['DateTime']
);
and then create a form control with it using
echo $this->Form->control('end_time', ['type' => 'datetime']);
However, I get the error Cannot find template named 'DateTime'.
I have created the basic template code
<?php
$this->Form->setTemplates([
'DateTime' => '<p {{attrs}}>Test template</p>'
]);
But I have no idea where in the folder structure to put it? In most plugins I have looked at it is in a helper file, but I wonder if this is the default way to do it? What are my options? And how do i tell CakePHP to load it? What is the preferred way of doing this?
Thank you!
If you want your widget to come with default string templates, then you could for example define them in the widget itself, by adding it to the string template instance that is being passed to the widget's constructor. You'd do it in the widget's render() method though, it wouldn't work properly in the constructor, as widget instances are being reused, ie they are only being constructed once, for example:
public function render(array $data, ContextInterface $context)
{
if (!array_key_exists('customDateTime', $this->_templates->getConfig())) {
$this->_templates->add([
'customDateTime' => '<p {{attrs}}>Test template</p>',
// ...
]);
}
// ...
}
Another option is to put the string templates in a config file:
// in path_to_your_plugin/config/form_helper_templates.php
<?php
return [
'customDateTime' => '<p {{attrs}}>Test template</p>',
// ...
];
and ask the users to load the form helper string templates in their view templates when they want to use your widgets:
$this->Form->templater()->load('YourPluginName.form_helper_templates');
Both options will integrate properly with the form helper, so that users can still override the templates by setting custom templates either via FormHelper::setTemplates(), StringTemplate::load()/add(), or the templates option for FormHelper::control().
I think you should use Cells for it.
Take a look at: https://book.cakephp.org/3/en/views/cells.html
Using Twig I render a particular view. I need this view to be translated into a language I choose. I display the view using:
return $this->setup->twig->display($view, $params);
Where $view is the name of the *.html.twig template and $params is an array with the parameters I need to pass.
However, if I want to translate the template before displaying it, how I have to do it?
Currently I have included .yml files for different languages and I have also replaced the text inside the views with the appropriate corresponding values from the yml file.
Apart from everything else, I have also loaded the Twig translator in a file separate from the rest of the project. It has the following code:
require dirname(__DIR__) . '/vendor/autoload.php';
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\ArrayLoader;
class Translation
{
public $translator;
public function translator()
{
$this->translator = new Translator('fr_FR');
$this->translator->addLoader('array', new ArrayLoader());
$this->translator->addResource('array', array(
'Symfony is great!' => 'J\'aime Symfony!',
), 'fr_FR');
var_dump($this->translator->trans('Symfony is great!'));
}
}
$show = new Translation;
$show->translator();
And it really displays the translation.
Still, I have no idea how to connect everything together....
Did you try to set the locale before rendering your twig view?
public function exampleAction(Request $request) {
$locale = 'de'; // Set the language
$request->setLocale($locale);
$content = $this->renderView($view, $params);
// Maybe return to default locale....
}
I created my prestashop module, with a hook to display my specific search form.
public function hookDisplayTopColumn($params)
{
$this->context->controller->addCSS($this->_path.'css/modelfilter.css', 'all');
$this->context->controller->addJS($this->_path.'js/modelfilter.js');
$marque = $this->getSubCategories($this->marquesCategory);
$this->context->smarty->assign(array(
'marques' => $marque,
));
return $this->display(__FILE__, 'form_model.tpl');
}
JS and CSS files are not included. To find why, I added a parse line in classes/controller/FrontController.php :
public function addMedia($media_uri, $css_media_type = null, $offset = null, $remove = false, $check_path = true)
{
echo 'addMedia '.$media_uri."<br/>\n";
And the result is : all css/js files appears before the beginning of the page (just after <body>), but my files comes just before displaying form_model.tpl
Please, how to make my files to be called in the good time ?
You shall not use $this->context->controller->addCSS and addJS outside of hookDisplayHeader().
When the header of your page is built hookDisplayHeader() is called to add headers elements. Once this hook is done, the header is built and can't be changed.
So when the hook hookDisplayTopColumn() is called, the header is already built.
To add your files you have to implement the hookDisplayHeader() in your module:
public function hookDisplayHeader($params)
{
$this->context->controller->addCSS($this->_path.'css/modelfilter.css', 'all');
$this->context->controller->addJS($this->_path.'js/modelfilter.js');
}
And remove those lines from hookDisplayTopColumn().
Ok I have a controller class in Yii that I want to use a different view folder aside from using its default view folder.
The natural behavior is when a $this->render("<view file>"); you would use the following to navigate your view file in the project...
"//" navigates project default view folder
"/" navigates current theme view folder
or do not use anything to select a view automatically in the
controller's default view folder
but my problem is i'm not rendering a view file but a STATIC PAGE that resides in /pages folder of a certain view folder. The static page I want to navigate is a static page the resides in my current theme folder views but the default is the controller navigates the static page inside the /protected/view folder
I tried also this override to modify the controller's view folder. I put this code in my controller that I want to render static pages in a theme folder
public function init(){
$this->layout = "//layouts/script";
$this->viewPath = "/js";
}
but the problem is the viewPath is readOnly variable.
Now my question is how I can render static pages that resides in my current theme's view folders?
NOTE: please if you don't understand my question, please don't down vote. I'm open to change and explain my problem for you as possible as I can
When you're overriding the actions method in your SiteController, somehow, you need to change the CViewAction's basePath property. It defaults to pages, as the documentation says.
Could you try something like this?
public function actions()
{
return array(
'page'=>array(
'class'=>'CViewAction',
'basePath'=>'path/to/your/theme/folder'
),
);
}
create a helper class for yourself and declare this method (change filepaths and other stuff):
public static function renderInternal($_viewFile_, $_data_ = null, $_return_ = false) {
// we use special variable names here to avoid conflict when extracting data
if (is_array($_data_)) {
extract($_data_, EXTR_PREFIX_SAME, 'data');
} else {
$data = $_data_;
}
$viewsDir = '/protected/views/internals/';
if ($_return_) {
ob_start();
ob_implicit_flush(false);
require(getcwd() . $viewsDir . $_viewFile_ . '.php');
return ob_get_clean();
} else {
require(getcwd() . $viewsDir . $_viewFile_ . '.php');
}
}
Use it/call it:
MyHelperClass::renderInternal( 'myviewfile', array( /* YOUR DATA */ ), /* RETURN CONTENTS OR NOT */ )
NOTE: Change $viewsDir to your desired directory.
try this in your any site controller or any controller..
public function actions()
{
return array(
'page'=>array(
'class'=>'CViewAction',
),
);
}
or refer this link...
http://www.yiiframework.com/wiki/22/how-to-display-static-pages-in-yii/
Help me figure out why isn't my form getting styled a la sites/all/modules/pecapture/themes/pecapture-displayform.tpl.php
Here's my code:
/**
* Implementation of hook_theme()
*/
function pecapture_theme() {
$path = drupal_get_path('module', 'pecapture') . '/theme';
return array(
'pecapture_displayform' => array(
'arguments' => array('form' => NULL),
'template' => 'pecapture-displayform',
'path' => $path,
),
);
}
Basically this says that theme files are in the module/theme folder ($path)
There is a theme function pecapture_displayform($form = NULL), called using theme('pecapture_displayform', $form) where $form is a Drupal form array
There is a template file pecapture_displayform.tpl.php at $path
function pecapture_block($op = 'list', $delta = 0, $edit = array()) {
$block = array();
if ($op == "list") { // Generate listing of blocks from this module, for the admin/block page
$block[0]["info"] = t('Persistent E-mail Capture Form Block');
}
else /* if ($op == 'view') */ { // Generate our block content
$block['subject'] = ''; //'Persistent E-mail Capture Form';
$block['content'] = pecapture_displayForm();
}
return $block;
} // function pecapture_block
This says that when you are viewing the block, use the function pecapture_displayForm() to generate the contents. $block gets php print()ed
/**
* Callback for pecapture_theme
*/
function pecapture_displayform() {
return drupal_get_form('pecapture_blockform');
}
This says return the html formatted drupal form array (for output)
function pecapture_blockform(&$form_state) {
/* the form, standard ... */
This is the form contents, it's typical.
I've tried calling the theme function explicitly in pecapture_displayform:
return theme('pecapture_displayform', $form);
and
return theme('pecapture_displayform', drupal_get_form($form));
So why is the form not going through pecapture-displayform.tpl.php ?
There's two basic ways of creating themes from a module - using a theme function, or using a template. In both cases, you need to register the themes in the hook_theme function for your module (pecapture_theme). That part of your example looks right.
If you register a theme function, you then create the theme function, and call it theme_themename. If you register a template (like you did) you use an optional template_preprocess function and a template. Template_preprocess functions are called template_preprocess_themename and are passed, by reference, an array of variables to be then passed to the template. Also, you should never directly call a theme function. Always uses theme('themename', $args) to access a theme so that drupal can handle it correctly (allows overriding, and correct variable preprocessing).
So, first of all, it looks like you're trying to directly call a theming function that drupal doesn't recognize as theme function. Second, you're using a template, so you need a function called template_preprocess_pecapture_displayform(&$vars) if you want to process the form before sending it to the template. Also make sure your template is called pecapture-display.tpl.php so it matches exactly the name you supplied in hook_theme except for the extension.
Also, it looks like you're trying to theme a form. So, you'll need to tell drupal_get_form to use your theme by including $form['#theme'] = 'pecapture_displayform' in your form function. You can output individual form elements in your theme by calling drupal_render($form['element']), calling drupal_render($form) will render any remaining un-rendered elements (drupal keeps track so they won't be rendered twice).
See http://api.drupal.org/api/drupal/developer--topics--forms_api.html/6 for more information on theming forms.
As long as you've specified the theme in your form function you won't need to call it explicitly, so you should be able to do
$block['content'] = drupal_get_form('pecapture_blockform');
in your block hook.