Kostache - before() method - php

Well, is there something like before() method in kostache module? For example, if I have a couple of PHP lines inside of the view file, I'd like to execute them separately inside of the view class, without echoing anything in the template itself. How can I handle that?

You can put this type of code in the constructor of your View class. When the view is instantiated, the code will run.
Here is a (slightly modified) example from a working application. This example illustrates a ViewModel that lets you change which mustache file is being used as the site's main layout. In the constructor, it chooses a default layout, which you can override if needed.
Controller:
class Controller_Pages extends Controller
{
public function action_show()
{
$current_page = Model_Page::factory($this->request->param('name'));
if ($current_page == NULL) {
throw new HTTP_Exception_404('Page not found: :page',
array(':page' => $this->request->param('name')));
}
$view = new View_Page;
$view->page_content = $current_page->Content;
$view->title = $current_page->Title;
if (isset($current_page->Layout) && $current_page->Layout !== 'default') {
$view->setLayout($current_page->Layout);
}
$this->response->body($view->render());
}
}
ViewModel:
class View_Page
{
public $title;
public $page_content;
public static $default_layout = 'mytemplate';
private $_layout;
public function __construct()
{
$this->_layout = self::$default_layout;
}
public function setLayout($layout)
{
$this->_layout = $layout;
}
public function render($template = null)
{
if ($this->_layout != null)
{
$renderer = Kostache_Layout::factory($this->_layout);
$this->template_init();
}
else
{
$renderer = Kostache::factory();
}
return $renderer->render($this, $template);
}
}

Related

Can't call parent method properties from inheritance class in php

I'am begginer in OOP PHP. I have code like this
class Index
{
public $activepage = true;
public $url;
public $page;
function __construct()
{
if ($this->activepage) {
$this->url = "Yes";
$this->page = "Home";
} else {
$this->url = "No";
$this->page = "Index";
}
}
public function show()
{
return $this->page;
}
public function showTest()
{
return "test";
}
}
class Home extends Index
{
function __construct()
{
echo $this->show();
}
}
$page = new Home;
My questions is :
Why I have blank page when I invoke Home class?
But when I change constructor in Home class like this echo $this->showTest();, it works. and displaying "test" on screen.
and what actually diferrent between my show method and showTest method in Index class?
When you add a __construct() in the Home class it overrides the construct from the parent class Index.
You can invoke the parent construct manually with:
function __construct()
{
parent::__construct();
echo $this->show();
}
You can call Parent class method like;
parent::show()

Yii function in layout file

I'm using Yii and I'm new to it.
I have a default main.php layout file and i need to make some data extractions from DB and cookies.
I've written 2 functions:
public function getRegionId() {
if(isset(Yii::app()->request->cookies['region_id'])) {
$sk = Yii::app()->request->cookies['region_id']->value;
settype($sk,integer);
return $sk;
} else {
return 1;
}
}
public function regionId2region($id) {
if(empty($id) or gettype($id)!=='integer') {
return null;
} else {
$reg = Regions::model()->findAll(array(
'condition'=>"alive=1 AND id=".$id,
));
return $reg;
}
}
Now it is not working in any controller. My question is: is it possible to make functions in the layout file or is there a way to pass data to layout file (so that it displays in all controllers)?
Move methods into Regions model and make it static. Or Create Helper class? contains just static methods.
class RegionHelper {
public static function getRegionId() {
if(isset(Yii::app()->request->cookies['region_id'])) {
return (int)$Yii::app()->request->cookies['region_id']->value;
}
return 1;
}
public static function regionId2region($id) {
if(empty($id) or gettype($id)!=='integer') {
return null;
} else {
$reg = Regions::model()->findAll(array(
'condition'=>"alive=1 AND id=".$id,
));
return $reg;
}
}
}
You can use BeforeAction in your controller, like this:
protected function beforeAction($action) {
//Define your variable here:
public $yourVaribale;
//do your logic and assign any value to variable
}
Now, you can use this variable in the view file:
view:
<h1><?php echo $this->yourVariable; ?></h1>
If your functions are located in the controller that calls the view, you could use the $this reference to access the function. Note the public access of the function.
class UserController extends Controller
{
// :
// :
public function fullName($a,$b) {
return $a.' '.$b;
}
}
...and in your view ...
<h1>Test for <?php echo $this->fullName('Tom', 'Jones'); ?></h1>
If the function is in your model, there are a few choices.
class User extends Activerecord
{
// :
// :
public function fullName($a,$b) {
return $a.' '.$b;
}
}
You could pass the model through the render function,
class UserController extends Controller
{
// :
// :
public function actionDisplayView {
$userModel = User::model()->findByPK(1);
$this->render('user_view', array('model' => $model));
}
}
and directly call the function in the view.
< h1 >Test for <?php echo $model->fullName('Tom', 'Jones'); ?>< / h1 >
or, if you did not pass the function, you could call the function in the view (or helper classes). Watch the scope.
class User extends Activerecord
{
// :
// :
// NOTE: You won't have access to $this.
static public function fullName($a,$b) {
return $a.' '.$b;
}
}
and in the view
< h1 >Test for <?php echo User::fullName('Tom', 'Jones'); ?>< /h1 >

Action_Helper in separte module does not get loaded

I followed this great article http://weierophinney.net/matthew/archives/246-Using-Action-Helpers-To-Implement-Re-Usable-Widgets.html, but currently i can't get work my simplified example.
PROBLEM The preDispatch does not get loaded.
I created new module user (there is also controller UserController, i hope this wont mess up the loading).
I have added two files in user.
Bootstrap.php - under module user
class User_Bootstrap extends Zend_Application_Module_Bootstrap {
public function initResourceLoader() {
$loader = $this->getResourceLoader();
$loader->addResourceType('helper', 'helpers', 'Helper');
}
protected function _initHelpers() {
Zend_Controller_Action_HelperBroker::addHelper(
new User_Helper_HandleLogin()
);
}
New folder under /user/helpers and class HandleLogin.
class User_Helper_HandleLogin extends Zend_Controller_Action_Helper_Abstract {
protected $view;
public function preDispatch() {
echo 'called';
if (($controller = $this->getActionController()) === null) {
return;
}
$this->createProfileWidget();
}
public function createProfileWidget() {
if (!$view = $this->getView()) {
return;
}
$view->user = '<h2>HELLO WORLD</h2>';
}
public function createLoginForm() {
}
public function getView() {
if ($this->view !== null) {
return $this->view;
}
$controller = $this->getActionController();
$view = $controller->view;
if (!$view instanceof Zend_View_Abstract) {
return;
}
//$view->addScriptPath(dirname(__FILE__) .'/../views/scripts');
$this->view = $view;
return $view;
}
}
And lastly added into layout.phtml the output.
<?php echo $this->user ?>
is init() function of User_Helper_HandleLogin works? is User_Bootstrap works? :) maybe you forget resources.modules[] = in config.ini?

Smarty custom plugin to use base class

Here is my class that gets called on each page:
class ActionHandler {
var $smarty = NULL;
public function __construct() {
if($this->smarty == NULL){
$this->smarty = new Smarty();
$this->smarty->template_dir = TEMPLATE_DIR;
$this->smarty->compile_dir = COMPILE_DIR;
}
}
public function do_something($page_id) {
return $page_id + 1;
}
}
Now I have a custom plugin for smarty that I want to use in my template:
function smarty_function_something($params, &$smarty) {
return ActionHandler::do_something($params['page_id']);
}
However I get Fatal error: Using $this when not in object context.
I see why but don't know how to get around this. Any ideas?
Try making the do_something a static member of ActionHandler
class ActionHandler {
public static $smarty = NULL;
public function __construct()
{
if($this->smarty == NULL)
{
$this->smarty = new Smarty();
$this->smarty->template_dir = TEMPLATE_DIR;
$this->smarty->compile_dir = COMPILE_DIR;
}
}
public static function do_something($page_id)
{
return $page_id + 1;
}
}
As your trying to access a non static method i *think that the __construct gets executed before the method is available, but as you have not created an instance of the object, the keyword $this does not exists.
you have to create specific static methods. if your going MyObject::SomeMethod($param)
you should also take a look at Object Auto Loading and Auto Initializing objects via static methods.
also you don't need to specifically define the value to public static $smarty = NULL; as Null is a default value of any new variable, just do
public static $smarty;
going a little more indepth with your problem you should add a singleton method like so..
class ActionHandler
{
public static $smarty;
public static $singleton;
public function __construct()
{
if($this->smarty == NULL)
{
$this->smarty = new Smarty();
$this->smarty->template_dir = TEMPLATE_DIR;
$this->smarty->compile_dir = COMPILE_DIR;
}
}
public static GetSingleton()
{
if(self::$singleton == null)
{
self::$singleton = new ActionHandler();
}
return self::$singleton;
}
public static function do_something($page_id)
{
$_this = self::GetSingleton();
return $page_id + 1;
}
}
You omitted a few pieces of code: instantiation of either the Smarty or ActionHandler object, registration of the template function, template content, and Smarty::display() call, but in my own testing your code works fine. In none of your code do you attempt to use $this while not in an object context.
If you have additional code to post (preferably, the full reduction that still triggers the error) that may help with debugging.
smarty-test.php:
<?php
include 'Smarty.class.php';
class ActionHandler {
var $smarty = NULL;
public function __construct() {
if($this->smarty == NULL){
$this->smarty = new Smarty();
$this->smarty->template_dir = __DIR__ . '/t';
$this->smarty->compile_dir = __DIR__ . '/tc';
$this->smarty->plugins_dir = __DIR__ . '/plugins';
}
}
public function do_something($page_id) {
return $page_id + 1;
}
}
$ah = new ActionHandler;
$ah->smarty->display('index.tpl');
plugins/function.something.php:
<?php
function smarty_function_something($params, &$smarty) {
return ActionHandler::do_something($params['page_id']);
}
t/index.tpl:
Test: {something page_id=1}
Output:
Test: 2

In Zend-Framewok plugin, how to do somthing simular to $this->view->foo =...;?

i wrote a small plugin, so i will be able to get the name of the controller in each view.
but idk how to "pass" a parameter to the view (do sumth like $this->view->foo =...;).
class Zend_Extension_Controller_Plugin_GetControllerName extends Zend_Controller_Plugin_Abstract
{
public function __construct()
{
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$this->view->controllerName = $request->getControllerName();
}
}
what can i write instead of $this->view->controllerName so it will work?
Try this:
$view = Zend_Layout::getMvcInstance()->getView();
$view->controllerName = $request->getControllerName();
You can use the helper broker to get an instance of the view. Something like this should work:
Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer')->view->foo = 'bar';
Take this example as basis:
class Plugin_Sidebar extends Zend_Controller_Plugin_Abstract {
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
if($request->getModuleName() == 'admin')
{
return;
}
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
if (null === $viewRenderer->view) {
$viewRenderer->initView();
}
$view = $viewRenderer->view;
$Categories = new Model_DbTable_Categories();
$view->menuItens = $Categories->getMenu();
}
}

Categories