I'm working with Joomla 3's MVC 12.1 platform and running into some issues with getting template overrides to work.
My Component has 3 controllers: stores, coupons, sales.
For each of these controllers I call my view similiar to this:
$paths = new SplPriorityQueue;
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/stores', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/stores/tmpl', 'normal');
$view = new StoresViewsStores(new StoresModelsStore, $paths);
$view->setLayout('default');
// Render our view.
echo $view->render();
Only deference between them is switching the view/model/directories out respectively.
As long as I don't include any overrides in my template everything works as expected. However as soon as I include overrides things get wonky.
If I add a com_stores/stores/default.php into my template, my stores get overridden correctly however the coupons and sales controllers start pointing to the stores override instead of their own folders.
Is their something that i'm missing that is making each of the controllers point to the same override?
Just for reference here is what is in for the paths in each controller.
Stores:
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/stores', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/' . $viewName . '/tmpl', 'normal');
Sales:
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/sales', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/' . $viewName . '/tmpl', 'normal');
Coupons:
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/coupons', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/' . $viewName . '/tmpl', 'normal');
Thanks for the help
Finally found the solutions. I started by tracing through The component to see what being loaded. Turns out everything was being forced through my stores controller. So I made a slight change in how my component checks to see which controller to use.
$controller = $app->input->get('controller','stores');
to
$controller = $app->input->get('view','stores');
One thing to note is that all of my views match match my controller name perfectly so i didn't have to do anything special to know this will work.
Related
I am using LengthAwarePaginator class to "transform" collection into the paginator object. Everything works like a charm, but I need necessarily to change pagination page name. When i use setPageName() method- the page name inside url changes from default "page" to whatever I need to, but pagination links are not working at all- by clicking, the next page contents don't appear, even the url has its custom page name for pagination.
I read everywhere that this was bug before, but now its claimed it is fixed- although it gives the same bug as before this Laravel fix somewhere at v. 5.0.
PS: I need to do this by setPageName method.
PS2: If this is a bug again, why to not solve it if we found out.
Here is my code:
Controller
$currentPage=LengthAwarePaginator::resolveCurrentPage()-1;
perPage=1;
// $items is collection variable
$currentPageBlogResults = $items->slice($currentPage * $perPage, $perPage)->all();
$items= new LengthAwarePaginator($currentPageBlogResults, count($items), $perPage);
$items->setPageName('special');
$items->setPath('main-category');
View
#foreach($items as $items)
.....
#endforeach
{{$items->links()}}
It's not a bug (I guess). You're resolving current page with LengthAwarePaginator::resolveCurrentPage() but it has own page name (defaults to "page"). You have two options:
$currentPage = LengthAwarePaginator::resolveCurrentPage('special') - 1;
or
LengthAwarePaginator::currentPageResolver(function () {
return 'special';
});
For each entry in the database, there is a corresponding image whose file name is the same as the unique ID of that database entry, eg an entry with ID '4' has the header image title '4.png'. I want to display the relevant image to the entry currently displayed, but I can't quite get the code below to work:
$img = asset('images/header/' . $img_id . '.png');
I've verified that $img_id works, and the images are displayed when if I just use the direct path to them - ie 'images/header/4.png'.
Your code snippet seems to be ok. You should be using it in the view like:
<img src="<?= asset('images/header/' . $img_id . '.png') ?>">
Ideally you could opt for an accessor to deal with this. In your model, add this:
public function getImgAttribute()
{
return '<img src="'. asset('images/header/' . $this->attributes['id'] . '.png') .'">';
}
Now you can use it in your views like $model->img.
I'm a newbie on Joomla developing and I'm trying to fix an old administration module made by 'someone before me'. Module's been developed using MVC Components, it has several CRUDs and I'm stucked at deleting an item. The template view adds the toolbar icon like this:
JToolbarHelper::deleteList('', 'paises.delete', JTOOLBAR_DELETE);
It also has at the list controller (DistribuidoresControllerPaises), the getModel function:
public function getModel($name = 'Pais', $prefix = 'DistribuidoresModel', $config = array('ignore_request' => true))
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
The model class:
class DistribuidoresModelPais extends JModelAdmin
When selecting an item on the list, and clicking the trash button an empty page opens with this ending:
administrator/index.php?option=com_distribuidores&view=pais
If I come back to grid, the item still remains.
Any suggestion?
Thanks in advance
You can debug this by enabling debugging from Joomla configuration or you can try to to check with exit with in "delete" function of "paises" controller and can check you get item ids in post request or not.
Also you are using view "pais" also using model "pais" then why you are using "paises" controller for delete function, you should use "pais" controller to delete.
Also provide delete function which you are using to delete items, it may contain some issue.
I'm trying to display a Joomla 2.5 component in a module.
In my module entrypoint I have:
JLoader::import('joomla.application.component.model');
JLoader::import( 'quizzes', JPATH_SITE . '/components/com_questions/models' );
JLoader::import('joomla.application.component.controller');
if (!class_exists('QuestionsControllerQuizzes')) {
require_once (JPATH_SITE . DS . 'components' . DS . 'com_questions/controllers' . DS . 'quizzes.php');
}
$quiz_controller = new QuestionsControllerQuizzes(false, $params->get('poll'));
$quiz_controller->execute( JRequest::getVar('task','load') );
I tried to debug it and it seems that can't load the correct view. Seems to looking for a generic com_content in $this->basePath.
The strange thing is that if I load the module in a page where the component is loaded, it display correctly.
Any idea how to succesfully display the component output in a module?
Try this: How to display Joomla component in a module
and remember your controller should include a function for the task!
Is there a way to check if an element exists for a view?
I want to load a different element according to a category it belongs to but not all categories have an element for it...
As of CakePHP version 2.3 you can use the View's elementExists method:
if($this->elementExists($name)) { ... }
In older versions of 2.x you can do:
if($this->_getElementFilename($name)) { ... }
But sadly in version 1.3 it looks like the only way is to know the full path and do something like:
if(file_exists($path . 'elements' . DS . $name . $ext)) { ... }
That is what they do in the 1.3 source code, but there is some complexity around getting $path from various plugins and checking each of those paths. (See link below.)
Sources:
http://api.cakephp.org/2.3/class-View.html#_elementExists
http://api.cakephp.org/2.0/source-class-View.html#722
http://api.cakephp.org/1.3/source-class-View.html#380
set element name in controller:
$default_element = 'my_element';
$element = 'my_cat_element';
if ($this->theme) {
$element_path = APP . 'views' . DS . 'themed' . DS . $this->theme . 'elements' . DS . $element . DS . $this-ext;
} else {
$element_path = APP . 'views' . DS . 'elements' . DS . $element . $this-ext;
}
if (!file_exists($element_path)) {
$element = $default_element;
}
You can always load an element specific to a category 'on demand' by telling it so from the controller. For example:
Within Controller Action:
$this->set('elementPath', "directory_name/$categoryName");
Within the View (this can also be tried exactly within a Layout):
<?php
if (!empty($elementPath)) { // you can also set a default $elementPath somewhere else, just in case
echo $this->element($elementPath);
}
?>
In fact, there is even other ways to achieve this. If the element is going to be loaded within a layout, then the set() method shown above can be specified from the view itself. Or, it can even be fetched from url parameters, like:
Within the View or Layout:
<?php
$elementPath = $this->params['url']['category']; // note that the param array can vary according how you set the url; see http://book.cakephp.org/#!/view/963/The-Parameters-Attribute-params
echo $this->element($elementPath);
?>
Of course, you will always have to specify, but the same would go for checking if the file exists.