Including Joomla! 3 module in custom position on custom component - joomla

I've seen alot of examples of how to include modules on a custom joomla! component using JModuleHelper::getModules, however, when trying to include modules in a custom position, the array come back empty. Here's my code in my component's template:
<?php
jimport('joomla.application.module.helper');
$modules = JModuleHelper::getModules('comwhcustomer');
foreach ($modules as $module){
echo JModuleHelper::renderModule($module);
}
?>
You'll notice the position I'm passing the getModules function is comwhcustomer. This code is returning a blank array. If I pass "footer", I do successfully get the module in the footer position.
I'm using an adapted protostar tempalte and I have added the comwhcustomer position to the xml definition file for the template. I've created the module in module manager and in the position filed, I've selected the "comwhcustomer" position that shows up in the dropdown. On the modules manager page, I see the module listed in the position selected (comwhcustomer). I've confirmed in the database table #__modules that the position is saved correctly.
However, the array is still coming back empty on the getModules call. What am I missing?
Joomla version 3.4.1
Local environment
Windows IIS
PHP 5.4.24
MySQL db
PS - As an alternative, I have sucessfully loaded the module with JModuleHelper::getModule() however, none of the attributes I define in the module manager come over, because they're not supposed to. I'd like to use the method mentioned above so I can control the module behavior from the manager rather than attributes in the code, because this position will be used in multiple views of this component.
This is my first time posting to SO. I do appreciate the support :-)

itoctopus, you were exactly right! The module itself was not assigned to any pages, that's the piece I was not taking into consideration! Thank you so much for your help! I set it to display on all pages and it worked!
Of course, it doesn't show up on all the other pages because they do not contain a position called "comwhcustomer" so it is exactly what I was looking for!

Related

Joomla Terminology: view, layout, task and component development

I'm a developer and I am very confident with MVC pattern and have already developed a lot of webapp from scratch using php framework like symfony or yii.
I'm a little bit confused about joomla mvc and terminology and after googling a lot, read joomla book extensions guide, read on joomla website my doubt are still there.
What is confusing for me is the component mvc structure and how I have to set up "my way of think" about joomla mvc, for doing the things in the joomla way.
In particular I am used to reasoning in terms of controller/action (like in symfony and yii framework)
So the final list of all my webapp url will be
controller1/action1
controller1/action2
controller1/action3
controller2/action1
controller2/action2
Each controller's action will decide what view to render and what layout to use for showing the view.
In particular in these frameworks, the definition of a layout is exactly the mean of a layout. And the view is the "core part" of the page.
So I can have a view with a list of users and I can put this view inside a mobile layout or a desktop layout, or to build a view for mobile and put it only in the mobile layout and so on.
The final result about directory structure in my webapp is something similar to the following:
controllers/
controller1
controller2
controller3
models/
modelForTableA
modelForTableB
views/
controller1/
viewForAction1
viewForAction2
layouts/
mobileLayout.php
desktopLayout.php
and for me is very clear to understand.
So finally my questions are:
how would be the directory structure in joomla?
what are in joomla the definition of view, layout and task?
I need to clarify that I do not need an explaination about MVC works in general, but if I would achieve the same result as before, how I have to organize my code and my work?
Suppose that I want to build a component with the following "url"
userController/addUser
userController/editUser
userController/listUsers
userController/viewUserDetail
anotherController/addOperation
anotherController/editOperation
anotherController/myNonCrudOperation
Thank you very much
Routing in Joomla is slightly different. The SEF URLs are built from menu items, which in turn point to a View/Layout combination.
This turns things around: a controller is not bound to a specific View/Layout.
Let's make an example of the flow with the addUser functionality you mentioned as an example; I'll be referring to these files (but you'll have plenty more):
/controllers/user.php
/models/user.php
/views/useradd/view.html.php
/views/useradd/tmpl/default.php
/views/useradd/tmpl/default.xml
/controller.php
/router.php
As you can see the layouts are inside each view's tmpl folder.
router.php
Let's start from this last file: router.php defines our custom SEF rules so, after Joomla passes the call to our component (usually with the params
?option=com_componentname) we can takeover and interpret the URL as we wish. It is a bit hard to get started with but does provide the most flexibility and power. We don't really need to implement it at all for this simple example: so back to our registration now.
First step: show the "new user" form.
You would typically bind this to a menu item, pointing to the /views/useradd/tmpl/default.php; the /views/useradd/tmpl/default.xml contains the definition of the layout so it's available in the menu manager. Very often there is only one layout per view.
Control is passed to the view /views/useradd/view.html.php , and the view will then load an instance of its own model (automatically chosen based on the view name, you can load other models of course) to gather any initialization data.
The view then renders the layout, and presents it to the user.
The layout's responsibility includes generating a form with an appropriate action (endpoint) and security tokens if appropriate:
<form action="index.php?option=com_mycomponent">
<input type="hidden" task="user.save">
<?php echo JHtml::_('form.token');?>
as you see it doesn't really matter if you want to use <input or params on the url, and you can most often mix them.
Form interaction
For autocompletion the form may need to invoke some backend controller methods, i.e. the method emailAvailable() in the /controllers/user.php
It does not make sense to have such functionality indexed, so we'll invoke the method directly with a non-SEF url:
index.php?option=com_ourcomponent&task=user.emailAvailable
followed by any other parameter. This will work in both get and post.
The controller /controllers/user.php's emailAvailable() method will return a json structure and then invoke exit() as we don't want the CMS to kick in at all. An alternative solution is to add the param &format=json in the call.
{"email":"johndoe#example.com", "available":true}
Saving the data
When the user submits the form, processing is first handled by the controller since a task is specified. (see above task=user.save). Joomla will invoke the method save() in the controller /controllers/user.php.
This time, however, our controller is responsible for returning information to the user. After processing the data, it may choose to re-render the registration form showing an error, or a thank you page. In either case the controller simply sets the redirect, letting Joomla handle the rendering when appropriate.
$this->setRedirect(JRoute::_('index.php?option=com_yourcomponent&view=useradd', false));
More control
Each time a controller task is not specified, the display() method of the main controller is invoked. You can add custom logic there.
Joomla fires several events during a view rendering; these can be intercepted by a system plugin or - if you add in the calls - other kinds of plugins as well. You may even create your own types of plugins. Do not try to instantiate a view manually from a controller, as this may inhibit plugin firing.
Small insight,
1) Directory Structure
controllers/
controller1
controller2
controller3
models/
modelForTableA
modelForTableB
views/
layout1
2) View and layout and task
check this answer
3) More routing techniques with SEF.
Hope it helps.
solved with this. I cannot delete this question because there already exists other answer.
Could any moderator close or delete this? Thank you
https://joomla.stackexchange.com/questions/18774/joomla-terminology-view-layout-task-and-component-development/18799#18799

phpbb variable empty on custom page

I have a phpbb 3.1 forum, where I have put a html portal, (using the custom page tutorial)
I have included functions.php so I can use {S_USERNAME} and everything with the S_ in that page...
but, now I want to put the forum statistics, using, for example:
{TOTAL_USERS_ONLINE}
{LOGGED_IN_USER_LIST}
{TOTAL_POSTS}
and so on
The variables, are empty when using them in my page... is there any problem? I need to add something more than that file?
thanks!
The variables are mentioned are initialized in the page_header function in functions.php
In custom pages you always call that function to initialize common variables like the S_ variables you mentioned.
Since the loading of online users is a little heavier and not needed on every page, the function has a parameter $display_online_list to enable it.
Check the method signature and set $display_online_list to true
To display TOTAL_POSTS, you will need to add a bit of code, see the assign_vars call in index.php, $config is a global variable which should be available in every page.

joomfish rel=canonical

I am trying to display a rel="canonical" link in the header of a joomla 1.5 site when there is no translation for the main content.
I have succeeded in adding rel="alternative" pointing to the other languages by modifying the language selector module.
What I need to know is where in the joomfish code I can check to see if the main content is translated and and my code for the header.
I have looked in plugins->missing translation.php, and added the following code:
$doc=&JFactory::getDocument();
$getVars = JRequest::get( 'GET' );
$getVars['lang']='en';
$newURL = http_build_query($getVars);
$alternative=JRoute::_($newURL);
$customrel='<link rel="canonical" href="'.$alternative.'" />';
$doc->addCustomTag( $customrel );
The tag gets displayed in the head, but multiple times. I think this is to do with no translation results for menu items, modules and so on, so the code gets executed for each item. I just want it to execute for the main content item (be it com_content, or another component)
Thanks in advance

joomla + not render a module

I have developed a module for joomla 2.5 and it works just fine, the thing is I don't want it to be rendered when a certain view of a component is displayed but that view is not a menu link so I can't tell my module not to render when I don't want it to.
Two possibilities:
Assign that view to a menu item in a menu that is never shown. You can than hide the module as usual.
Since you have a custom module you could modify the module to check for the component and view and not render itself in certain cases.
One issue that you might have with "check for the component and view and not render itself in certain cases" is that if the module is in a module position that is supposed to "collapse" when there are no modules in it (e.g. a right or left column), it won't collapse because the module is still assigned (even though it's not rendering anything).
The issue is to do with where the decision is made to display the module. Is it a question of the module itself deciding when to render, or should the logic be somewhere else, that determines "on this page, should a particular module appear?". I suggest the latter.
A good solution for this is MetaMod Pro that allows you to build in conditions that determine whether other modules should appear on the page. You then put in a snippet of PHP to do the detection.
So the snippet might be:
if (! ($option == 'com_mycomponent' and $view == 'myview') ) return XXX;
// replace XXX with the module id of the module you want to disappear.
i.e. "if we're not on a page with mycomponent and myview, show module XXX".
Tip: the Pro version will allow the module to completely disappear if it's not included. The free version may leave some HTML behind.

Joomla: How to change template on a specific article

Is there a way to change the template on a specific article only?
Note that it should work without linking the article to any menu.
If you want the template override not to depend on the menu position than the standard joomla way of assigning a different template to a menu will not work. You will need to get your hands dirty and write some custom code. You will need to use the article_id as a trigger for template switch.
I did something like that at work but don't remember now how exactly this is achieved. I will post my code here as soon as I locate it.
EDIT: Found the code :)
You need to edit the file /includes/application.php, specifically the getTemplate() method. At the end of this method, just before:
// Fallback template
if (!file_exists(JPATH_THEMES.DS.$template.DS.'index.php')) {
$template = 'rhuk_milkyway';
}
you can add your condition for applying a custom template, like so:
//CUSTOM TEMPLATE FOR THE ARTICLE 13
if (JRequest::getVar('id')=='13' && JRequest::getVar('option')=='com_content') {
$template = $custom_template_name;
}
This will apply the custom template which name is inside the $custom_template_name to article with id=13. You can also use it to apply a different template to components, like I did with simplecaddy:
//TEMPLATE FOR SIMPLECADDY
if (JRequest::getVar('option')=='com_caddy'){
$template = 'shop';
}
You should really try to stay away from hard coding anything in to the template if it can be avoided. Not sure why you would specify that the article not be linked from a menu. The easiest way to accomplish this without having to write and code is to create a new menu, then add a menu item that links to the article you want to specify the template for. You don't have to put the menu in a module anywhere so it will never show up on the site, but it will show up in the menu assignment in the template manager.
You can do this with single articles, categories, sections, or even components. As long as you have a menu link to associate the template to. I always create an Admin only menu to put links that are needed to run the site, but do not need to be accessed by users.
As Brent said, avoid the temptation to modify core Joomla code! Doing this will likely stop you from doing Joomla upgrades 'cos you know it's going to break the core changes that you made.
Apart from the "hidden menu item" technique (which is useful but can break SEF URLs in some situations), a useful tool is Chameleon. This allows you to select specific articles/categories/sections (plus things like browser type, user group, component, whatever) and use these to trigger a certain template.
Though this is an old post, I thought I'd share my thoughts: You can easily change template on a single article, by implementing the onAfterInitialize() - function in a system plugin. No need to modify the Joomla core.
This works for Joomla 1.5, but should also work in 2.5:
function onAfterInitialise(){
if(true){ // f.ex. test for article ID or whatever
JRequest::setVar('template', 'beez'); // change template
}
}
In joomla 3.x versions, url-parameters are handled differently. The following was tested in joomla 3.4.8:
public function onAfterInitialise()
{
$app=JFactory::getApplication();
if(true){ // f.ex. test for article ID or whatever
$app->input->set('template', 'beez3');
}
}
More on writing plugins for Joomla here

Resources