Twig template engine shows odd information - php

I am first day user of Twig, and I have some strange behaviour of engine.
I push some information to my view:
class MainController extends Controller {
public function actionIndex()
{
$template = self::$twig->loadTemplate('index.php');
$title = 'CRUD интерфейс';
$projects = MainList::showAll();
$workers = CompanyWorker::showAll();
$roles = Role::showAll();
$namesOfProjects = Project::showAll();
echo $template->render(array(
'title' => $title,
'projects' => $projects,
'workers' => $workers,
'roles' => $roles,
'namesOfProjects' => $namesOfProjects
));
}
}
In the end I have a good result but in the end of HTML file twig shows me my controller object. Why it's happened?
It's my Twig initialisation:
abstract class Controller {
public $loader;
static $twig;
function __construct()
{
$this->loader = new Twig_Loader_Filesystem('views');
//$twig = new Twig_Environment($loader, array('cache' => 'cache'));
self::$twig = new Twig_Environment($this->loader);
}

I'm were blind 8[. I really missed 'print_r' func.

Related

Problems with class extending UserDefinedForm in Silverstripe 4

I've been stuck on this for a while now and I can't see where I'm going wrong.
I've made a class that extends the UserDefinedForm so I can have a page that also has a UserDefinedForm on it. The form loads on the page, but it isn't as easy as just saying $Form on the template file, instead I have to make and call the following function:
public function getUserForm() {
$page = UserDefinedForm::get()->byID($this->ID);
$controller = UserDefinedFormController::create($page);
return $controller->Form();
}
So when I call that function on the template it displays the form, however, none of my field rules are applied and when submitting the form it takes me to a blank page with "/finished" appended to the URL: "https://example.com/finished".
Can someone please help me out here, would be much appreciated.
I will put my code down below.
Class extending the UserDefinedForm:
<?php
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\FileHandleField;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Assets\Image;
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\Forms\DropdownField;
use SilverStripe\UserForms\Model\UserDefinedForm;
use SilverStripe\UserForms\Control\UserDefinedFormController;
use SilverStripe\UserForms\Model\EditableCustomRule;
class Package extends UserDefinedForm {
private static $db = [
'Date' => 'Text',
'Location' => 'Text',
'Availability' => 'Enum(array("Available","Hidden","Sold Out"))',
'Extras' => 'HTMLText',
'NeedTo' => 'HTMLText',
'Price' => 'Text'
];
private static $has_one =[
'Photo' => Image::class,
];
private static $has_many =[
'FileAttachments' => 'PackageFile'
];
private static $many_many = [
'SacredTexts' => 'ImportantText'
];
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', Injector::inst()->create(FileHandleField::class, 'Photo'));
$fields->addFieldToTab('Root.Main', new TextField('Date', 'Date'));
$fields->addFieldToTab('Root.Main', new TextField('Location', 'Location'));
$fields->addFieldToTab('Root.Main', new TextField('Price', 'Price'));
$fields->addFieldToTab('Root.Main', new HTMLEditorField('Extras', 'Extras'));
$fields->addFieldToTab('Root.Main', new HTMLEditorField('NeedTo', 'What you need to know'));
$fields->addFieldToTab('Root.Main', new DropdownField('Availability', 'Availability', singleton('Package')->dbObject('Availability')->enumValues()));
$fields->addFieldToTab('Root.Main', new GridField('SacredTexts', 'Important Texts', $this->SacredTexts(), GridFieldConfig_RecordEditor::create()),'Date');
$fields->addFieldToTab('Root.Main', new GridField('FileAttachments', 'File Attachments', $this->FileAttachments(), GridFieldConfig_RecordEditor::create()),'Content');
return $fields;
}
/* Look up SS4 docs on SS Sitetree URL parse function and what needs to be namespaced */
function onBeforeWrite () {
parent::onBeforeWrite ();
if($this->Name){
$this->Slug = str_replace(' ','-', strtolower($this->Name));;
}
}
public function ShortContent( $word_limit = 20 ) {
$NoHTML = htmlspecialchars_decode(strip_tags($this->NewsText),ENT_QUOTES);
$words = explode( ' ', $NoHTML );
return implode( ' ', array_slice( $words, 0, $word_limit ) );
}
public function ParentEvent(){
return $this->Parent()->URLSegment;
}
public function getUserForm() {
$page = UserDefinedForm::get()->byID($this->ID);
$controller = UserDefinedFormController::create($page);
return $controller->Form();
}
public function hasUserForm() {
if (count($this->getUserForm()->Fields()) > 1) {
return $this->getUserForm();
}
}
}
I figured it out.
Turns out the class controller I was extending to override wasn't working, instead it was referring to the UserDefinedFormController. I fixed it by copying the following function from the UserDefinedForm class:
public function getControllerName()
{
return UserDefinedFormController::class;
}
and copying it into my extended class from UserDefinedForm and renaming the return statement to the name of the class, for example:
public function getControllerName()
{
return PackageController::class;
}

drupal 8 error to render template twig with controller

I am trying to render a template with my controller but does not work
it show me this error :
LogicException: The controller must return a response (Hello Bob! given). in Symfony\Component\HttpKernel\HttpKernel->handleRaw() (line 163 of core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php).
My function :
public function helloAction($name) {
$twigFilePath = drupal_get_path('module', 'acme') . '/templates/hello.html.twig';
$template = $this->twig->loadTemplate($twigFilePath);
return $template->render(array('name' => $name));
}
In Drupal 8 you either return a Response object or a render array from a controller. So you have two options:
1) Place the rendered template into a Response object:
public function helloAction($name) {
$twigFilePath = drupal_get_path('module', 'acme') . '/templates/hello.html.twig';
$template = $this->twig->loadTemplate($twigFilePath);
$markup = $template->render(array('name' => $name));
return new Response($markup);
}
2) Place the rendered template into a render array:
public function helloAction($name) {
$twigFilePath = drupal_get_path('module', 'acme') . '/templates/hello.html.twig';
$template = $this->twig->loadTemplate($twigFilePath);
$markup = $template->render(array('name' => $name));
return array(
'#markup' => $markup,
);
}
Also you can Use the second option without custom template, doing this:
public function helloAction($name) {
$markup = "<p> Without custom Template</p>";
return array(
'#markup' => $markup,
);
}
class ClientController extends ControllerBase implements ContainerInjectionInterface ,ContainerAwareInterface {
protected $twig ;
public function __construct(\Twig_Environment $twig)
{
$this->twig = $twig ;
}
public function index()
{
$twigFilePath = drupal_get_path('module', 'client') . '/templates/index.html.twig';
$template = $this->twig->loadTemplate($twigFilePath);
$user = ['user' => 'name'] ; // as example
$markup = [
'#markup' => $template->render( ['users' => $users ,'kit_form' => $output] ),
'#attached' => ['library' => ['client/index.custom']] ,
];
return $markup;
}
// this is called first then call constructor
public static function create(ContainerInterface $container)
{
return new static(
$container->get('twig') ,
);
}
}
this full example to render twig by dependency injection from controller

Default scope in Yii 1.1

AR model Player:
public function scopes()
{
return array(
'proleague' => array(
'condition' => 'mode = "proleague"',
),
'main' => array(
'condition' => 'mode = "main"',
),
);
}
Using model Player:
Player::model()->
proleague()->
with('startposition')->
findAllByAttributes(... here some condition ...);
^^^ That's all ok. Scope-condition will be executed. But...
In my project I have many places where any scope for Player model doesn't specified and in this cases I need use this scope-condition as default:
'main' => array(
'condition' => 'mode = "main"',
)
If I add defaultScope() method to Player model like this
public function defaultScope()
{
return array(
'condition' => 'mode = "main"',
);
}
the next code
Player::model()->
proleague()->
with('startposition')->
findAllByAttributes(... here some condition ...);
won't run correct. I won't get mode = "proleague" condition, becouse I'll use defaultScope() with mode = "main".
Any suggestions? How can I resolve the problem?
You should just use the resetScope(true) method. It "removes" the defaultScope filter.
$model = Player::model()->resetScope(true)->proleague();
create a new Class for this.
<?php
## e.g. protected/models/
class MyCoreAR extends CActiveRecord
{
/**
* Switch off the default scope
*/
private $_defaultScopeDisabled = false; // Flag - whether defaultScope is disabled or not
public function setDefaultScopeDisabled($bool)
{
$this->_defaultScopeDisabled = $bool;
}
public function getDefaultScopeDisabled()
{
return $this->_defaultScopeDisabled;
}
public function noScope()
{
$obj = clone $this;
$obj->setDefaultScopeDisabled(true);
return $obj;
}
// see http://www.yiiframework.com/wiki/462/yii-for-beginners-2/#hh16
public function resetScope($bool = true)
{
$this->setDefaultScopeDisabled(true);
return parent::resetScope($bool);
}
public function defaultScope()
{
if(!$this->getDefaultScopeDisabled()) {
return array(
'condition' => 'mode = "main"',
);
} else {
return array();
}
}
}
In your code:
// no default scope
$model = Player::model()->noScope()->proleague();
// with default scope
$model = Player::model()->proleague();

How to get access to the model in the view - Symfony 2

I have the following model:
class Person
{
public $name;
function __Construct( $name )
{
$this->name = $name;
}
}
I have the following controller:
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', $people);
}
}
How do I get access to the model array in the view. Is there a way to access the model directly or do I have to assign a property like so:?
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', array( "model" => $people ) );
}
}
View:
<?php
foreach( $model as $person )
{
echo $person->title;
}
?>
The problem with the above will be that it can be changed by a user to
return $this->render( 'FrameworkBundle:Navigation:index.html.php', array( "marybloomingpoppin" => $people ) );
With the example view you used, you already had the correct implementation:
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', array( "model" => $people ) );
}
}
You mentioned the concern that somebody could change the assignment in the controller, but this is something you always have if somebody changes the name of a variable only in one place and not in all. So I don't think this is an issue.

Laravel send default variables to layout

Having the following class that is extended by other controllers
class Admin_Controller extends Base_Controller
{
static $admin_layout = 'admin.layouts.default';
public function __construct()
{
parent::__construct();
$role_object = User::find(Auth::user()->id)->roles()->get();
$role = $role_object[0]->attributes['name'];
such as:
class Admin_Draws_Controller extends Admin_Controller
{
public $restful = true;
public function __construct()
{
$this->layout = parent::$admin_layout;
parent::__construct();
}
public function get_index()
{
$view = View::make('admin.templates.draws');
$this->layout->content = $view;
}
}
How can I send the $role variable to admin.layouts.default so I can have it when ever the view is loaded?
The point of "global" $role variable is to avoid to have to call it in all of my View::make() like the following:
$view = View::make('admin.templates.articles',
array(
'fields' => $fields,
'data' => $results,
'links' => $links,
'role' => 'role here'. // I don't want to add this where ever I call the View::make
)
);
$this->layout->content = $view;
and just do an echo $role like, in my header.blade.php
I ended up doing the following, which works.
Controller
// Example of variable to set
$this->layout->body_class = 'user-register';
$view = View::make('modules.user.register', array(
'success' => true,
));
$this->layout->content = $view;
My default.layout.php view
<body class="<?php echo isset($body_class) ? $body_class : '' ;?>">
#include('partials.header')
{{ $content }}
#include('partials.footer')
The variable, can be easily used in any other context within the view.

Categories