Zend Framework 2 custom style for each user - php

I am building an application for companies which sends anonymous-links to customers for filling out a questionnaire. The company should be able to change the colors and the logo of the questionnaire to reflect the affiliation to the company's CI.
My idea was to make a folder for every company (in my case, represented as doctrine entity Client) and load the layout's style.css and logo.png etc. dynamically from this folder.
The question: how do I implement this? How can I change a variable in the layout file from the controller? Or do I have to place the whole layout inside the view.phtml file for the ViewModel?
Thanks in advance!

If I had to have several layouts depending on some condition.
I would make the layouts for every company, set them in module.config.php
'view_manager' => array(
'template_path_stack' => array(
'module' => __DIR__ . '/../view/',
),
'template_map' => array(
'layout/company1' => __DIR__ . '/../view/layout/company1.phtml',
'layout/company2' => __DIR__ . '/../view/layout/company2.phtml',
)
),
Then in gloabal.php or in the same module.config.php would add some options:
'companies_layouts' => array(
'IDofComapny1' => 'layout/company1',
'IDofComapny2' => 'layout/company2',
)
And finally in the controller would do something like this:
public function indexAction()
{
$sm = $this->getServiceLocator();
// Getting company identifier
$companyId = $this->params()->fromRoute( 'companyId' );
// do something
...
$this->layout( $sm->get('Config')['companies_layouts'][$comanyId] );
return new ViewModel();
}
If you just need to set css depending on some conditions.
You can just do this in the view file:
switch( true ){
case some condition:
$css = 'file1.css';
break;
case some condition:
$css = 'file2.css';
break;
}
$this->headLink()->appendStylesheet( $css );
And in the layout file you should have next line:
<head>
...
<?= $this->headLink() ?>
...
</head>

You need to set style.css and logo file path according to company name in you action and then you can access this vairable in you layout also as same as you access in view file.
And set you css with headLink() function. and assign logo file in layout header.
You don't need to place layout code in view file.
Write below code on you controller. you can also access style variable in you layout.
return new ViewModel(array( 'style' => $style ,'logo' => $logo));

Related

Use variable outside views phalcon

I'm using Phalcon and his capability to make easier the translation with his Class Translate. So far I'm passing the t variable from the index to all the views, right when I set up volt, like this :
$view = new View();
$view->setViewsDir(WEBSITE_PATH.'/views/');
// Return a translation object
$view->t = new Phalcon\Translate\Adapter\NativeArray([
"content" => $localization
]);
That is working, but I also have pages to translate outside from the folder views, in .php, not .volt.
How can I share/set/pass this variable 't' to other places?
You can register the translations in your dependency injector like
$di->setShared('translations', function() use($di) {
// Include or set your translations here, must be an array
$translations = ['Phalcon' => 'Falcon', 'Word' => 'Translation'];
return new \Phalcon\Translate\Adapter\NativeArray(array(
'content' => $translations
));
});
Then you can call the translations in any controller like
$this->translations->_('Phalcon')
and in views like
<?=$this->translations->_('Word') ?>
Further reading: https://docs.phalconphp.com/en/latest/reference/translate.html

how to run yii widget when button clicked

I have this widget:
<?php
class Search extends CWidget
{
public $dataProvider = null;
public function init()
{
$criteria = new CDbCriteria();
if ( isset($_GET['file']) ) {
$criteria->compare('fileName', $_GET['file'], true, 'OR');
$criteria->compare('tags', $_GET['file'], true, 'OR');
}
$this->dataProvider = new CActiveDataProvider("Files", array(
'criteria' => $criteria,
//'countCriteria' => $criteria,
'pagination'=>array(
// results per page
'pageSize'=>1,
),
));
}
public function run(){
$this->render('site/result', array(
'dataProvider' => $this->dataProvider,
'pages' => $this->dataProvider->pagination,
));
}
}
?>
how I can run this widget only when the search button is clicked, and how to view its result in the view reuslt that is located in the folder site
Maybe I misunderstood you, but I think you have a little confusion about widget. Avoid making a
lengthy answer, I made a model in below
Question 1: How I can run this widget only when the search button is clicked?
The idea is that you put the widget content into hidden div, and then add a jQuery script to show it after the search button is clicked
<div id='search-result' style="display:none"><?php $this->widget(...) ?></div>
<script>
$('#search-button-id').click({
// do something
$('#search-result').show();
})</script>
Question 2: how to view its result in the view reuslt that is located in the folder site?
Imao, I recommend you don't do this. The widget is independant part, you can use it for many specific purposes & many locations of your project, so just put a simple view for widget to render in its own, instead of trying to render a view outside widget's scope. It should look like below
/your-app/protected/extensions/widgets/search/Search.php
/your-app/protected/extensions/widgets/search/views/result.php // view for rendering

how to set common code once in YII

i wanted to know in which file we can set common code, for example i wanted to set timezone to UTC, instead of putting same code in all controllers file is there any way to put the code once and it will be reflect in all files.
You may create your file in ''components'' folder. You can see this folder in "protected" folder.
Or you can write your code in controller.php
File path: webroot/protected/components/Controller.php
Can you please try to add the codes in bootstrap.php file
If you need to set the server time you can check here.It is a simple method
Change time zone
Use application params, ie:
// config part
return array(
// ...
'params' => array(
'myParam' => 123
)
// ...
);
// Then in app use
Yii::app()->params['myParam'] // Will return 123
You can also create your own params holder as component, ie:
// config part
'components' => array(
'myConfigs' => array(
'class' => 'ext.MyConfigs'
'myParam1' => 123,
'myParam2' => 'blah'
)
)
// Component in extensions
class MyConfigs extends CComponent
{
public $myParam1;
public $myParam2 = 'defaultValue';
}
// Then in app use it:
Yii::app()->myConfigs->myParam1 // will return 123

Extending custom config array in Codeigniter within a view file

I'am using a codeigniter 2.x. What i need is to insert a values into an array of config/template.php from inside of a view file /views/home.php.
I've created a custom config file application/config/template.php:
$config['site_name'] = "Sitename";
$config['site_lang'] = "En-en";
$config['page_name'] = "Pagename";
$config['css_page'] = "default";
$config['alias'] = "";
$config['head_meta'] = array(
'description' => 'description',
'keywords' => 'meta, keywords',
'stylesheets' => array(
'template.css'
),
'scripts' => array(
'jquery.js',
'template.js'
),
'charset' => 'UTF-8'
);
$config['sidebars'] = array();
Then, i use application/views/template/template.php as my main HTML layout, where at the beginning I include a file application/views/template/includes/inc-tpl-cfg.php which globalize my configurations for a template into an one file with arrays, so i could access them a little bit easier. Here is the content of that inc-tpl-cfg.php:
<?php
// No direct acces to this file
if (!defined('BASEPATH')) exit('No direct script access allowed');
/* Template configuration needs to be defined to make them accessible in the whole template */
$cfg_template = array(
'sitename' => $this->config->item('site_name'),
'sitelang' => $this->config->item('site_lang'),
'pagename' => $this->config->item('page_name'),
'csspage' => $this->config->item('css_page'),
'charset' => $this->config->item('charset','head_meta'),
'description' => $this->config->item('description','head_meta'),
'keywords' => $this->config->item('keywords','head_meta'),
'stylesheets' => $this->config->item('stylesheets','head_meta'),
'scripts' => $this->config->item('scripts','head_meta'),
'sidebars' => $this->config->item('sidebars')
);
/* Template variables */
$cfg_assetsUrl = base_url() . 'assets';
// If pagename exists than concatenate it with a sitename, else output only sitename
if(!empty($cfg_template['pagename'])){
$title = $cfg_template['pagename'] . ' - ' . $cfg_template['sitename'];
}else{
$title = $cfg_template['sitename'];
}
And one part in my main template layout is block with sidebars:
<div id="tpl-sidebar">
<?php foreach($cfg_template['sidebars'] as $sidebar):?>
<?php $this->load->view('modules/'. $sidebar);?>
<?php endforeach ;?>
</div>
And at last, it loads a application/views/home.php into the specific div block inside applications/views/template/template.php. This is a /views/home.php:
<?php
// No direct acces to this file
if (!defined('BASEPATH')) exit('No direct script access allowed');
// Page configuration
$this->config->set_item('page_name','Homepage');
$this->config->set_item('css_page','home');
$this->config->set_item('alias','home');
?>
<p>
WELCOME BLABLABLA
</p>
</h3>
There is a section where i can define/overwrite a default values from config/template.php and use a specific ones for each views. So my questions is, how can i extend a $config[sidebar] array inside this view file by inserting some new items, for exemple: recent.php,rss.php etc... ?
Sorry for a big code.
Thanks in advance.
Why don't you set config variables in controller?
Views are not meant for logics.
You shouldn't do that in the views, setting that data should be done from the controllers.
The views should only handle view logic, not setting the logic itself...
Then you pass the vars from the controller, when it's all set and ready to go, into the view.
Ok, i got it:
this is what i should insert inside of a views/home.php:
$this->config->set_item('sidebars',array(
'recent',
'rss'
));
Thanks anyway.

Passing url parameters to Zend_Navigation using an XML-file

I am using Zend Framework 1.10.8.
I want to create a breadcrumb section in my layout.phtml. There are some links in my menu that have dynamic url parameters like http://mydomain.com/editor/edit/id/42
I try to figure out how to pass id=XXX to Zend_Navigation, while XXX comes from the database and is different in every request.
One solution I found so far is adding a property e.g. params_id to my xml declaration:
in configs/navigation.xml
<pages>
<editor>
<label>Editor</label>
<controller>editor</controller>
<action>edit</action>
<params_id>id</params_id>
<route>default</route>
</editor>
</pages>
and in the controller looping through the pages and dynamically adding my parameter id = 42 (while 42 would be retrieved from the request object in the final version)
$pages = $this->view->navigation()->getContainer()->findAllBy('params_id','id');
foreach ($pages as &$page) {
$page->setParams(array(
'id' => 42,
'something_else' => 667
));
}
As adding dynamic url parameters seems such a basic requirement for Zend_Navigation I am quite sure that my solution is too complicate, too expensive and there must be a much simplier solution "out of the box".
It is very simple. Just write in your XML
<pages>
<editor>
<label>Editor</label>
<controller>editor</controller>
<action>edit</action>
<params>
<id>42</id>
<someting_else>667</something_else>
</params>
<route>default</route>
</editor>
</pages>
Here is example to do it dynamically based on database data
First define Navigation loading plugin. Name the file Navigation.php and place it in application/plugins/ directory. Here's an example of such plugin:
class Plugin_Navigation extends Zend_Controller_Plugin_Abstract
{
function preDispatch(Zend_Controller_Request_Abstract $request)
{
$view = Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer')->view;
//load initial navigation from XML
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml','nav');
$container = new Zend_Navigation($config);
//get root page
$rootPage = $container->findOneBy('sth', 'value');
//get database data
$data = Model_Sth::getData();
foreach ($data as $row) {
$rootPage->addPage(new Zend_Navigation_Page_Mvc(array(
'module' => 'default',
'controller' => 'examplecontroller',
'action' => 'exampleaction',
'route' => 'exampleroute',
'label' => $row['some_field'],
'params' => array(
'param1' => $row['param1'],
'param2' => $row['param1']
)
)));
}
//pass container to view
$view->navigation($container);
}
}
Then in you Bootstrap init this plugin
protected function _initNavigation() {
Zend_Controller_Front::getInstance()->registerPlugin(new Plugin_Navigation());
}
An update: I finally ended up throwing away the xml file. What I do now:
I wrote a plugin (see Daimon's approach)
in this plugin I configure my navigation structure as an array, the
dynamic parameters are retrieved from Zend_Request
then I init the navigation using this array

Categories