I am working on a 3rd party library in PROJECTROOT/libraries/mylib. have a controller in mylib/controllers, which is working. li3 tells me it expects a view in PROJECTROOT/app/views/ -- how can I load a view from mylib/views instead of app ?
That can be easily achieved by setting the render paths in a controller. You probably want to do that for every controller in mylib, so a BaseController that all controllers extent from is a good idea. You can then use lithiums default called method _init() to setup the configurtion like that:
class BaseController extends \lithium\action\Controller {
public function _init() {
parent::_init();
$this->_render['paths'] = array(
'template' => array(
LITHIUM_APP_PATH . '/views/{:controller}/{:template}.{:type}.php',
'{:library}/views/{:controller}/{:template}.{:type}.php',
),
'layout' => array(
LITHIUM_APP_PATH . '/views/layouts/{:layout}.{:type}.php',
'{:library}/views/layouts/{:layout}.{:type}.php',
),
'element' => array(
LITHIUM_APP_PATH . '/views/elements/{:template}.{:type}.php',
'{:library}/views/elements/{:template}.{:type}.php',
),
);
}
You can have a look at it here: https://github.com/bruensicke/radium/blob/master/controllers/BaseController.php
Please note, that i set it up that way, so the application can overwrite specific views in order to customize it further.
Also, there is an issue/pull-request on github regarding that topic, have a look here:
https://github.com/UnionOfRAD/lithium/pull/650
Related
The goal: Unit test an InputFilter in Zend Framework 2.
The problem: A mocked DbAdapter is needed.
As I am relatively new to Unit Testing I just got started with mocking classes. After doing a lot of research I'm still unable to find a proper solution for my problem so here we go with my filter to start things off:
class ExampleFilter extends Inputfilter
{
protected $dbAdapter;
public function __construct(AdapterInterface $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
public function init()
{
$this->add(
[
'name' => 'example_field',
'required' => true,
'filters' => [
['name' => 'StringTrim'],
['name' => 'StripTags'],
],
'validators' => [
[
'name' => 'Db\NoRecordExists',
'options' => [
'adapter' => $this->dbAdapter,
'table' => 'example_table',
'field' => 'example_field',
],
],
],
]
);
}
}
Without the need of an adapter, testing this filter would be rather easy. My problem is to create the Filter in my TestClass as seen here:
class ExampleFilterTest extends \PHPUnit_Framework_TestCase
{
protected $exampleFilter;
protected $mockDbAdapter;
public function setUp()
{
$this->mockDbAdapter = $this->getMockBuilder('Zend\Db\Adapter')
->disableOriginalConstructor()
->getMock();
$this->exampleFilter = new ExampleFilter($this->mockDbAdapter);
}
}
When creating the filter like this the ExampleFilter class will end up saying that I did provide a wrong class to its constructor. It's receiving a mock object when expecting one of type Zend\Db\Adapter\Adapter.
I could create a real adapter of course but I want to avoid performing actual queries to the database as it is a unit test and this would go far beyond the border of my unit to test.
Can anyone tell me how I can achieve my goal of testing the filter with a mocked DbAdapter?
Well... As I was commenting on gontrollez hint I already smelled my mistake. I had to create a mock of 'Zend/Db/Adapter/AdapterInterface' instead of just '/Zend/Db/Adapter'.
Thanks for bringing me on the right path anyway gontrollez :)
Answering the following question Kendo MVC ListView Editing
Kendo in MVC uses a folder with the following path View/Shared/EditorTemplates
inside this folder you must insert all the templates you call by name, example:
#(Html.Kendo().ListView<temp.Models.YourTable>(Model)
.Name("LisView")
.TagName("div")
.ClientTemplateId("templateView") => here goes the template for data
.DataSource(dataSource => dataSource
.Model(m => m.Id("ID"))
.ServerOperation(false)
.Read(read => read.Action("ActionRead", "Controller"))
)
.Editable(edit => edit.TemplateName("EditTmpl"))
)
EditTmpl => // this template is the one that you must store in the folder that I refer above.
hope this helps.
I am developing a module for prestashop (basically, it's a very custom import of data and the only thing I need is to have a form and process data). I have created controller class derived from the ModuleAdminController but the problem is where should I put the tpl file containing the look of my custom form?
I realize that I can put tpl file to the templates but I want to keep all files within my module folder, is it possible (probably somewhere like "/views/templates/admin")?
This is the most easy method to create a basic admin controller / action in Prestashop 1.6
Create basic configuration :
./config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>foo</name>
<displayName><![CDATA[Foo]]></displayName>
<version><![CDATA[2.1.3]]></version>
<description><![CDATA[Bar.]]></description>
<author><![CDATA[your-name]]></author>
<tab><![CDATA[administration]]></tab>
<is_configurable>0</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>
./foo.php
if (!defined('_PS_VERSION_'))
exit;
class BarcodeEasyPrint extends Module
{
public function __construct()
{
$this->name = 'foo';
$this->tab = 'administration';
$this->version = '1.0.0';
$this->author = 'your-name-here';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Foo');
$this->description = $this->l('Bar.');
if ((int)Tools::getValue('p'))
$this->page = (int)Tools::getValue('p');
}
}
You need to create the controller with base functions :
./controllers/admin/AdminFooController.php
class AdminFooController extends ModuleAdminController {
public function __construct() {
$this->bootstrap = true;
parent::__construct();
}
public function createTemplate($tpl_name) {
if (file_exists($this->getTemplatePath() . $tpl_name) && $this->viewAccess())
return $this->context->smarty->createTemplate($this- >getTemplatePath() . $tpl_name, $this->context->smarty);
return parent::createTemplate($tpl_name);
}
public function initContent(){
parent::initContent();
$tpl = $this->createTemplate('content.tpl')->fetch();
/* DO STUFF HERE */
$posts = array();
$this->context->smarty->assign('posts', $posts);
}
}
You can use boostrap directly in the template file :
./views/templates/admin/content.tpl
<div class="row">
<div class="col-md-6">
</div>
<div class="col-md-6">
</div>
</div>
If it is an admin module only, then you will have no need to create any views. Because Prestashop provides a nice structure for admin section which is easy to use and we dont need to use any views or .tpl files. For admin section, normally three types of views or .tpl files are required, one for data display in grid, second for form and third for displaying a single record.
Prestashop already created .tpl files for them which you can find in "admin_folder/themes/default/templates". In our controllers for admin, for form and for data grid, we just create arrays and PS handles to view the form and data grid according to the arrays we created.
So if you need a custom form at admin, then create a public function renderForm and create the form array in it, like below:
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Video'),
'image' => '../img/admin/tab-genders.gif'
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Video Title:'),
'name' => 'title',
'lang' => true,
'size' => 70,
'hint' => $this->l('Invalid characters:').' 0-9!<>,;?=+()##"�{}_$%:',
'required' => true
),
array(
'type' => 'textarea',
'label' => $this->l('Video Code'),
'name' => 'video_code',
'rows' => 5,
'cols' => 70,
'desc' => $this->l('Place the embed code for the video')
),
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button'
)
);
return parent::renderForm();
} /* End of render member */
For other fields, checkout other prestashop admin controllers and you will see that how easily we can create forms in PS using that simple definitions in the arrays and we dont need to create .tpl files.
For front end, we can use the new modules MVC structure, where our module folder have sub folders for controllers (controllers/front, controllers/admin) , views and models .
Hope this will help you.
Thank you
You need to use the helper form, here is the documentation for it, it is really easy to use ;) .
http://doc.prestashop.com/display/PS15/HelperForm
You also can find more information about how and where to use helper form, look for the function getContent() and displayForm().
http://doc.prestashop.com/display/PS15/Creating+a+PrestaShop+module
unfortunately any document not exist to point directly to solve this question but hear i have some URLs really useful and you should combine theme and get your realize:
http://presthemes.com/prestashop-news/modules-classes-and-controller-override-by-julien-breux-4.html
http://doc.prestashop.com/display/PS15/Diving+into+PrestaShop+Core+development
http://doc.prestashop.com/display/PS15/New+Developers+Features+In+PrestaShop+1.5
http://blog.belvg.com/how-to-implement-a-controller.html
best regards
extending the answer from #altafhussain create a folder views/templates/admin in your module and place your customview.tpl
Than append the free text block as below.
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Legend')
),
'input' => array(
array(
'type' => 'free',
'label' => 'Whatever label text',
'desc' => $this->display(__FILE__,'views/templates/admin/customview.tpl'),
'name' => 'FREE_TEXT',
'required' => false
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button'
)
);
return parent::renderForm();
}
I have a method in my Users Controller called view, which should display a specified (by URL) user:
public function view($username = null) {
$this->User->username = $username;
if (!$this->User->exists()) {
throw new NotFoundException('Няма такъв потребител!');
}
if (!$username) {
$this->Session->setFlash('Няма такъв потребител!');
$this->redirect(array('action' => 'index'));
}
$this->set('user', $this->User->read());
}
And in the route config:
Router::connect('/:username', array('controller' => 'users', 'action'=> 'view'), array('username' => '^([a-z0-9])+$'));
But when I try: www.example.com/Username it returns a fatal error: Missing controller.
I tried also this:
Router::connect('/users/:username', array('controller' => 'users', 'action'=> 'view'), array('pass' => array('username'), 'username' => '^([a-z0-9])+$'));
Unfortunately for this sort of setup using /:username is too simple, it will pretty much override every single other route. To do this effectively ( + the proper CakePHP way) you need to setup a custom route, here is mine which pretty much achieves the same thing. Just replace "product" with "user" for most cases, read through it though, to make sure you understand what's going on..
Look at my routes config as well if you still can't work it out.
If you want to route /user/dunhamzz to a profile you would set it up like this:
Router::connect('/user/:username',
array('controller' => 'users', 'action' => 'view'),
array('pass' => array('username')
);
Then your view action simply gets the username as the first argument:
public function view($username) {
}
Hi I am having problem while matching Kohana 3 custom route, it seems like every thing is correct but URL doesnot match with route. Following are settings in my bootstrap.php file:
Kohana::init(array(
'base_url' => '/basepath/',
'index_file' => 'index.php'
));
/**
* Attach the file write to logging. Multiple writers are supported.
*/
Kohana::$log->attach(new Log_File(APPPATH.'logs'));
/**
* Attach a file reader to config. Multiple readers are supported.
*/
Kohana::$config->attach(new Config_File);
/**
* Enable modules. Modules are referenced by a relative or absolute path.
*/
Kohana::modules(array(
'auth' => MODPATH.'auth', // Basic authentication
// 'cache' => MODPATH.'cache', // Caching with multiple backends
// 'codebench' => MODPATH.'codebench', // Benchmarking tool
'database' => MODPATH.'database', // Database access
'image' => MODPATH.'image', // Image manipulation
'orm' => MODPATH.'orm', // Object Relationship Mapping
// 'unittest' => MODPATH.'unittest', // Unit testing
'userguide' => MODPATH.'userguide', // User guide and API documentation
));
/**
* Set the routes. Each route must have a minimum of a name, a URI and a set of
* defaults for the URI.
*/
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
Route::set('category_images', 'cat/<category>', array('category'=>'[a-z\-_\.]+'))
->defaults(array(
'controller' => 'categoryimages',
'action' => 'index',
));
Route::set('user_images', '<username>/images(/<pageid>)', array('username'=>'[a-z\-_\.]+', 'pageid'=>'[1-9][0-9]*'))
->defaults(array(
'controller' => 'userimages',
'action' => 'index',
));
Route::set('dynamic_image', 'image/thumbnail/<size>/<id>/<image>', array('size'=>'s|m|z', 'id'=>'[0-9]+', 'image'=>'.+'))
->defaults(array(
'controller' => 'image',
'action' => 'thumbnail'
));
Attached is the error mesage:
Here is target controller, to show naming conventions if there is problem in that:
<?php
class Controller_Categoryimages extends Controller_Template {
public $template = 'template';
public $images_per_page = 15;
// show images of a user
public function action_index() {
//code here
}
Please tell if some one have any idea that why it is not matching the URL.
thanks in advance guys.
Your default route should be last, as it's a catch all. I'd recommend you delete it completely. It's currently matching default first, and trying to load the Contoller_Cat class with action sky.