Placing a widget inside a custom widget with custom itemView yii2 - php

I want to create a custom widget named 'IssueList' which will extend 'ListView'.
<?php
namespace frontend\components;
use yii\base\Widget;
use yii\widgets\ListView;
class IssueList extends Widget{
public $dataProvider;
public function init(){
parent::init();
}
public function run(){
return ListView::widget([
'dataProvider' => $this->dataProvider,
'itemOptions' => [
'class' => 'item issue-item'
],
'options' => [
'class' => 'issue_list'
],
'itemView' => '_issueListView',
'layout' => '{items}{pager}',
]);
}
}?>
However the ListView has a custom itemView. When rendering the widget I get this error
The view file does not exist:
/var/www/clients/client1/web1/frontend/views/comments/_issueListView.php
Its obviously looking in the wrong directory, how do I change this?

itemView is passed to yii\base\View render() which is responsible for rendering view. So you can change view path how you want, using aliases if needed:
Renders a view.
The view to be rendered can be specified in one of the following
formats:
path alias (e.g. "#app/views/site/index");
absolute path within application (e.g. "//site/index"): the view name starts with double slashes. The actual view file will be looked
for under the view path of the application.
absolute path within current module (e.g. "/site/index"): the view name starts with a single slash. The actual view file will be looked
for under the view path of the current module.
relative view (e.g. "index"): the view name does not start with # or /. The corresponding view file will be looked for under the view path
of the view $context. If $context is not given, it will be looked for
under the directory containing the view currently being rendered
(i.e., this happens when rendering a view within another view).
If you want it to be more dynamic, you can pass closure to itemView with the following signature:
function ($model, $key, $index, $widget) {
...
}
See docs for itemView here.
Besides the API Documentation, rendering views and specifying paths is described in official docs in Views (Rendering Views) section.

Related

Custom configuration files in CakePHP 3

I have a CakePHP 3.3.14 application where I've created 2 subdirectories, webroot/data/downloads/ and webroot/data/master
I want to put these paths in a custom configuration file and reference them in a Controller. But I can't see how to do this.
I've followed the documentation on Configuration but it's not very clear.
So what I've done:
Created config/my_config.php
The above file defines an array:
return [ 'downloadsPath' => 'webroot/data/downloads/', 'masterPath' => 'webroot/data/master/' ];
In config/bootstrap.php I've put: Configure::load('my_config', 'default');
How do I then use this in a Controller? If I put Configure::read('my_config.masterPath'); it gives an error saying: Class 'App\Controller\Configure' not found
If I add use Cake\Core\Configure; to the top of my Controller, that clears the error but the return value is null:
debug(Configure::read('my_config.masterPath')); // null
Loading another config file just extends the default App.config. So just use \Cake\Core\Configure::read('masterPath') and you are good.
EDIT
If it is your goal to have different config paths you could do it like this:
// my_config.php
return [
'MyConfig' => [
'masterPath' => '...',
...
]
];
Then use the config like this:
<?= \Cake\Core\Configure::read('MyConfig.masterPath') ?>

Loading core scripts such as jQuery in Yii 2

I've been having a hard time trying to figure out how to load jQuery or other CORE scripts in Yii 2.
In Yii 1 it seemed this was the way:
<?php Yii::app()->clientScript->registerCoreScript("jquery"); ?>
In Yii 2, $app is a property of Yii, not a method, so the above naturally doesn't work, but changing it to:
<?php Yii::$app->clientScript->registerCoreScript("jquery"); ?>
produces this error:
Getting unknown property: yii\web\Application::clientScript
I couldn't find any documentation for Yii 2 about loading core scripts, so I tried the below:
<?php $this->registerJsFile(Yii::$app->request->baseUrl . '/js/jquery.min.js', array('position' => $this::POS_HEAD), 'jquery'); ?>
Whilst this loads jQuery in the head, a second version of jQuery is also loaded by Yii when needed and hence causes conflict errors.
Additionally, I don't want to use Yii's implementation of jQuery, I would prefer to maintain my own and hence that is why I am doing this.
How can I load jQuery and other core files without Yii loading duplicate copies of them when it needs them?
In order to disable Yii2's default assets you can refer to this question:
Yii2 disable Bootstrap Js, JQuery and CSS
Anyway, Yii2's asset management way is different from Yii 1.x.x. First you need to create an AssetBundle. As official guide example, create an asset bundle like below in ``:
namespace app\assets\YourAssetBundleName;
use yii\web\AssetBundle;
class YourAssetBundleName extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'path/file.css',//or files
];
public $js=[
'path/file.js' //or files
];
//if this asset depends on other assets you may populate below array
public $depends = [
];
}
Then, to publish them on your views:
use app\assets\YourAssetBundleName;
YourAssetBundleName::register($this);
Which $this refers to current view object.
On the other hand, if you need to only register JS files into a view, you may use:
$this->registerJsFile('path/to/file.js');
yii\web\View::registerJsFile()
And if you need to only register CSS files into a view, you may use:
$this->registerCssFile('path/to/file.css');
yii\web\View::registerCssFile()
You can remove the core jQuery from loading like so:
config/web.php
'assetManager' => [
'bundles' => [
// you can override AssetBundle configs here
'yii\web\JqueryAsset' => [
'sourcePath' => null,
'js' => []
],
],
],

How to change Yii Error Handler on the fly?

In Yii's config.php we have this statement which declares which Controller is the default and only-one Error-Handler within the application:
'errorHandler' => array(
'errorAction' => 'site/error',
),
So, I need to have an actionError() under my SiteController, to get the errors previewed in my site, but this is not what I really need.
I am trying to change the Yii::app()->errorHandler->errorAction on the fly, throughout my custom-controllers who extend the base CController (Yii's base controller).
Till now, I have tried something like this:
<?php
class AdminController extends CController {
public $layout = '//layouts/admin';
public function init() {
parent::init();
Yii::app()->errorHandler->errorAction = '/admin/error';
}
}
But gives no results, nor hope. Note that I also have this URL configuration:
'/admin' => '/admin/home',
'/admin/<controller:\w+>' => '/admin/<controller>',
'/admin/<controller:\w+>/<action:\w+>/<id:\d+>' => '/admin/<controller>/<action>',
'/admin/<controller:\w+>/<action:\w+>' => '/admin/<controller>/<action>',
And this means I have a whole Controllers-Views group named admin, and they are stored in following directories:
protected/controllers/admin
protected/views/admin
So by that logic, I have ErrorController in both: admin and controllers root, and by the same structure in the views directory.
That's what I have tried, and I really appreciate help, so thank you all in advance!
You should try this :
Yii::app()->setComponents(array(
'errorHandler'=>array(
'errorAction'=>'/admin/error'
)
));
http://www.yiiframework.com/doc/api/1.1/CModule#setComponents-detail

Zend Framework 2.1, output from one controller action to another controller

I am using zend framework 2.1. I am trying to load the output of my indexAction from my login controller inside of my index controller. The end result I am trying accomplish is to just have my login form loaded on the index page as if it is part of that view.
I have searched for a few hours with no avail. I have attempted to use $this->view->action, which i've seen in earlier versions of zf2 but that has not worked either.
Any information would be helpful.
Taken from this blog, which explains in depth why $this->view->action() has been removed from ZF2, an example how to use the forward() (ZF2 documentation) controller plugin:
You can forward all necessary data to another controller inside your index controller action using the forward() controller plugin like this:
public function indexAction() {
$view = new ViewModel();
$login_param = $this->params('login_param');
$login = $this->forward()->dispatch('App\Controller\LoginController', array(
'action' => 'display',
'login_param' => $login_param
));
$view->addChild($login, 'login');
return $view;
}
In your view, all you need to do is:
<?php echo $this->login; ?>
Please note that the forward() plugin might return a Zend\Http\PhpEnvironment\Response instead. This happens if you use a redirect() in your login controller / action.
Also, if the Servicemanager claims to not find App\Controller\LoginController, have a look in your module.config.php. Look for a section called controllers.
Example:
[...]
'controllers' => array(
'invokables' => array(
'LoginCon' => 'App\Controller\LoginController',
'IndexCon' => 'App\Controller\IndexController',
'DataCon' => 'App\Controller\DataController',
)
),
[...]
Here, there is an alias for your login controller called LoginCon, you should use this name as controller name in the dispatch() method instead.

Ajax tab in zii tab widget

Below i have an ajax tab example:
$this->widget('zii.widgets.jui.CJuiTabs', array(
'tabs' => array(
'StaticTab 1' => 'Content for tab 1',
'StaticTab 2' => array('content' => 'Content for tab 2', 'id' => 'tab2'),
// panel 3 contains the content rendered by a partial view
'AjaxTab' => array('ajax' => $this->createUrl('/AjaxModule/ajax/reqTest01')),
),
// additional javascript options for the tabs plugin
'options' => array(
'collapsible' => true,
),
));
but i don't know what happens in /AjaxModule/ajax/reqTest01.
There is a missing part in this example, the rendering view, and i don't know how to design it so that the ajax call to work. Thanks.
According to the code you have put up, specifically this line:
'AjaxTab' => array('ajax' => $this->createUrl('/AjaxModule/ajax/reqTest01')),
We know that we need ajaxmodule, ajax controller, reqtest01 action, so do the following steps:
First
Create a module, it'll have to be named AjaxModule.
Second
Create a controller in this AjaxModule named Ajax.
Third
Create an action within this Ajax controller, named ReqTest01.
Within this action you can either directly echo html, or use renderPartial(), to render a view file partially for ajax.
So your controller Ajax and the action within looks somewhat like this
<?php
class AjaxController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
public function actionReqTest01(){
// directly echoing output is hardly of any use, like echo "Directly echoing this";
$this->renderPartial('rendpar_ajax'); // renderPartial is way better as we have a view file rendpar_ajax.php that we can manipulate easily
}
}
Fourth
Now we can code the rendpar_ajax.php view file, create this file in the views folder of the ajaxController controller in the AjaxModule module.
<?php
// rendpar_ajax.php file for ajax tab
// have any code here, use widgets, form, html helper etc
echo "<h1>AjaxModule--AjaxController--actionReqTest01</h1>";
echo "<p>This view is partially rendered</p>";
Read more about creating modules, controllers, actions, and how they are used, and how the yii directory hierarchy works.
Good luck!
Edit: Note that to a view we can also pass dataproviders for getting complex dynamic views.

Categories