how can I override as well node/x/edit as node/x/add with just one panel? - drupal-6

I'm using durpal 6 and have some panel pages. The one for /node/%node/edit is overriding the node edit pages. but on my regarding node/add page the panel page is not applied.
Do I have to add a new page? There is a panel context "node add form" - if I add this, can I anyway use one panel page variant for as node/edit as node/add ? Or would I have to use 2 different forms ?

Finally resolved the problem. In our case it was a collision with the i18n module. I reported it to drupal.org but it seems it's working as designed.
In your case, if you are not using i18n, there may be some module overriding the node_page_edit on top of ctools. Check the menu_router table to see which function (module) is has their callback registered for the node/add/% and node/edit/% routes and then try to lower the weight of that module or increase the weight of ctools page manager. Clear your caches and check the callback for the node add and edit routes is page_manager_node_edit.
/**
* Entry point for our overridden node edit.
*
* This function asks its assigned handlers who, if anyone, would like
* to run with it. If no one does, it passes through to Drupal core's
* node edit, which is node_page_edit().
*/
function page_manager_node_edit($node) {
...
You can check my hack and the module author's comments here: http://drupal.org/node/1561046#comment-5997776

Related

Auto-collapse any item in PrimeFaces PanelMenu on page loading

I'm writing a Primefaces 5.1 portlet.
It consists in a unique page containing a panelMenu, and I need that it starts with any panel collapsed everytime a user change page (on page loading).
But, if I open a panel, then change page, it will start showing that panel still opened.
I wasn't able to find any option to achieve this goal (e.g. collapsed=true, ignoreCookie=true or something similar).
The only solution I found was the following Javascript code:
PrimeFaces.widgets.myPanelMenu.collapseRootSubmenu(PrimeFaces.widgets.myPanelMenu.headers);
The problem is that this code will collapse any opened panel (so on page loading user is able to see panel menu collapsing animation) but it seems it doesn't store this state in its cookie/localstorage... the result is that on any page loading user can see this animation.
I'm sure it doesn't save its state, because the only way to "solve" the problem is to manually re-open and re-collapse the panels... then, on following page change, these menus start closed (and there is no animation).
I also tried to use PrimeFaces.widgets.sideMenuPanel.saveState() after collapsing, but with no success.
Do you have any idea about?
Thank you...
I found a solution to the problem.
If you read my discussion with Kukeltje (comments on my question), you will find that latest Primefaces' versions will solve the problem.
Otherwise, if you want to avoid upgrade or modify sources, and you need a quick fix based on Javascript only please read the following part of the answer.
It directly works on the component's state using JavaScript.
First of all you need to have a variable reference to your component:
<p:panelMenu model="#{menuBackingBean.menuModel}" widgetVar="sidePanelMenu" />
Then you should add the following JS code on document ready:
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
// 1. On page loading collapses possible opened panels
panelMenu.collapseRootSubmenu(panelMenu.headers);
// following line is commented because it never should be necessary is not necessary (unless unexpected situation I never verified)
//clearSidePanelMenuPreferences();
// 2. Call the "clear preferences" actions on click on two tpe of links: first level are the panel link (used to open/close the menu) and second level are the destination links
// We need to fork also on the first level links to be sure it works after user clicks there then exit from the page in another way
panelMenu.headers.children("a").click(function(){setTimeout(clearSidePanelMenuPreferences, 500)}); // setTimeout is necessary because this event should be fired after preferences are written
panelMenu.headers.siblings().find("a").click(function(){clearSidePanelMenuPreferences();});
The function called to clear preferences are the following:
function clearSidePanelMenuPreferences() {
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
panelMenu.expandedNodes = []; // clear the opened panels lists
panelMenu.saveState(); // store this information
}
Hope it helps
Please check this block of code
PF('myPanelMenu').headers.each(
function(){
var header = jQuery(this);
PF('myPanelMenu').collapseRootSubmenu(header);
header.removeClass('ui-state-hover');
}
);
I prefer to do this in order to execute this method only once and keep the menu option selected.
$(document).ready(function() {
if(location.pathname == "/cotizador/" || location.pathname == "/cotizador/faces/login.xhtml"){
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
// 1. On page loading collapses possible opened panels
panelMenu.collapseRootSubmenu(panelMenu.headers);
panelMenu.expandedNodes = []; // clear the opened panels lists
panelMenu.saveState();
}
});

Load an Orchard Module in another

I have two modules which one of them is dependent on the other.
When I go to my home page, the "slave module" is loaded nicely, but when I go to the "master module" (which is routed) I can't see the first one.
How do I show or force the rendering of the slave shape in the master module?
I don't know how to explain better, so I'll just tell the exactly scenario.
I create a module called "Store" (the master module) that implements a route to "/Store/{optional_parameters}".
When i navigate to this url, I get the expected result without problems.
BUT, i create another module called "Search" (the slave module) which is dependent on the Store module and needs to be displayed in every page (just like navigation and footer).
I thought I managed to do it, doing this in the Display override on SearchDriver:
workContextAccessor.GetContext().Layout.Zones["Search"].Add(shape, "10");
Then if i navigate to "/"(or any route that isn't defined by me) i can see the search shape on the right spot, but if i navigate to "/Store" (or any route defined by me) i can't see anymore.
Btw, the StoreController has the "Theme" notation.
Why aren't you using a widget? That would just work and would be considerably less work. It would also be manageable without having to change code.

Rhodes Rhomobile - Override the layout behavior for a particular view

I need some help with a very specific case.
I would like to override the layout behavior for a particular view.
I did found the Rhodes documentation describing what to do.
(a copy of the Rhodes documentation is pasted at bottom of this text)
I tried to use the second alternative ("call the layout method on the controller to overwrite the default layout name") but it did not worked.
I assume I might have misunderstood how to code the controller or hopefully only have a syntax error...
See more information about the application below.
Could anyone please tell me how I should do it ?
What would be the right syntax ?
Or should I use another method ?
Thanks in advance.
Louis Deschenes
Here are some informations about the application and what I did:
Simple application
Build is for iPhone
Application start in "Calculator" view
"Calculator" view call "Control" view that call "Help" view
App structure:
app/
-> index.erb (Control view)
-> layout.erb (Standard layout)
-> calculatorlayout.erb (Customize layout for Calculator view)
-> calculator/
-----> index.erb (Calculator view)
-----> calculator_controller.erb (Controller to be able to override layout)
-> help/
-----> index.erb (Help view)
I created Calculator_controller.erb containning
require 'rho/rhocontroller'
require 'helpers/browser_helper'
class CalculatorController < Rho::RhoController
include BrowserHelper
layout :calculatorlayout (Thats what Rhodes doc mentionned to do)
As I said this does not work. Please tell me the right way to do it.
Note: As a temporily mesure I did a copy of app/calculatorlayout.erb into app/calculator/layout.erb
This does the rendering right when the app start in "Caculator" view,
but if I navigate to "About" view and back to "Calculator" view the rendering of the calculator is done with the standard layout.
--------Rhodes Documentation--------------------------------------------
If you would like to override or customize layout behavior, you can
call the render function with the following parameters:
render :action => 'index',
:layout => 'mycustomlayout', :use_layout_on_ajax => false
The first argument is the action you would like to render. Next is the
(optional) layout name, which assumes the application root as a base
directory. In the above example, Rhodes would look for a file called
“mycustomlayout.erb” in the application root directory (you also may
use :layout => false to disable the use of a layout template). The
use_layout_on_ajax argument tells Rhodes whether or not to use the
layout on Ajax calls (default is false).
You can call the layout method on the controller to overwrite the
default layout name:
layout :mycustomlayout
This will force the render call to use mycustomlayout.erb in place of
the default layout file for all actions of this controller.
In the controller, you need to specify an action method. The render method of an action is what handles the layout property. You cannot simply designate a layout for an entire controller. Below is an example controller file. You would then need an index.erb view file to correspond to the index action method.
CalculatorController.rb
require 'rho/rhocontroller'
require 'helpers/browser_helper'
class CalculatorController < Rho::RhoController
include BrowserHelper
def index
# perform any logic or fetch objects for the index.erb view
render :action => :index, :layout => 'calculatorLayout'
end
end
Unfortunately Rhodes has godawful documentation so its mechanics can be difficult to decipher. But I must mention that unfortunately Geoffrey is entirely wrong in this point:
You cannot simply designate a layout for an entire controller
Actually, you can simply designate a layout for a controller. There are tons of ways, but specifically you can do as the docs supposedly mention, just not in the way 'ideschenes' tried. If you inspect the source code in render.rb you would notice that RhoController defines a setter method for this exact purpose, which is a basic Ruby mechanic.
def self.layout(name)
#layout = name
end
Therefore you can either use self.layout = :layout_name or #layout = :layout_name inside the controller to define a default layout. I don't know the complexities of how it may be overridden, but this technique will allow you to set a default layout for any controller. I tested it myself.
There is also a method in RhoController which retrieves the layout name, and you can of course override this inside your own controller if you want to customize the behavior for choosing a layout.
def self.get_layout_name
#layout.nil? ? 'layout' : #layout
end

Magento :: Layout in Module

Is it possible to create a layout file inside of a module ? How ?
For what:
I want to add a some kind of statistics hit counter for products, and I don't want to override the products class, as that is already done by some module I'm using. Thus I thought it would be best to have a custom module with a block that would be called by a layout statement.
Of course I could easily edit my private local.xml or make changes to another layout-xml in the layout folder of my theme, but I want this feature to be available in all themes (independent of any selected theme).
Some constraints:
All code in one single module
... so that it is theme independent
... so that the module can be shared with others without them having to change anything (like theme files), so that the install/load of my module would be enough
I would also accept different approaches for my statistics hit counter loading (using the same constraints)
Yes it is possible. Just create your layout xml file in the following path: /design/frontend/default/default/layout/yourlayout.xml(or whatever your theme name is), and add a proper statement in your modules etc/config.xml:
<config>
<frontend>
<layout>
<updates>
<yourmoduleshortname>
<file>yourlayout.xml</file>
<yourmoduleshortname>
</updates>
</layout>
</frontend>
</config>
This sample is for frontend user, but adminhtml layouts can be updated in a similar manner. If something doesn't work, be sure to check if your layout is in the proper theme/package directory.
Edit:
Second approach:
You can use a controller of your own, which will extend the core functionality (one of the catalog controllers) - just rewrite it (or just product view action). Inside its action method add something like this:
$thiss->getLayout()->createBlock('namespacename/block','layout-block-name',
array('template' => 'relativepathtotemplate.phtml'));
$this->getLayout()->getBlock('content')->append($block);
run-original-parent-code();
Third approach:
Similar to the previous one, but you can use some event observer, and try Mage::getSingleton('core/layout'), and inject your block there. Not in all events the layout will be already available (try the post_dispatch family).
I don't really recommend the second and third approach, because if someone else wants to find where this 'magic' block comes from, it will most surely look int app/design/(...) directory. Finding it in your controller or model, may be very tricky...
If you don't want to display your statistic counter, you can also use events (like post_dispatch) to count the controller dispatches. Just create an observer attached to it, and store your data in the DB.

Magento _prepareLayout() called 5 times to many

** New EDIT **
so what I'm trying to do is this.
I want the to add new form elements generated by my module on the product view of the following url
http://magento.example.com/catalog/product/view/id/46
ultimately these elements will be determined to show up by a related table in my module
I expected that if I extended Mage_Catalog_Block_Product_View in my module as shown below I would be able to create a block in the product form that would contain such form fields, only if he are in the related table in my module
so I created a test.phtml file in
app/design/frontend/default/default/templates/<module>/test.phtml
then as you can see in my the View.php file described bellow I built the block and displayed it in the product view.
It did appear but 5 times too many. from the answers below this is normal so that answers the question as to why the it shows up five times but leaves the question what is the proper way to proceecd since this plan is not going to work
** End New Edit **
in my module I call _prepareLayout() and it does this 5 times when i pull up the page
here's my code
in
/app/code/local/Namespace/Module/Product/Veiw.php
class <Namespace>_<module>_Block_Product_View extends Mage_Catalog_Block_Product_View {
protected function _toHtml() {
return parent::_toHtml();
}
public function _prepareLayout() {
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'my_block_name_here',
array('template' => '<module>/test.phtml')
);
if ($block){
$this->getLayout()->getBlock('content')->insert($block)->toHtml();
}else{
echo "no block";
}
return parent::_prepareLayout();
}
}
NOTE:
I just noticed this also takes away the price availability qty and add to cart button. which is also a problem
EDIT
First I want to thank you all for your answers. Second i want to give you more context
the reason for choosing to do this in the module is that I don't want the block to show up on every product . What i have is a table of what I'll call custom options containing properties of the product sort of like hair color height weight etc and depending on what set of properties are attached to the product (if any) will depend on what html content will show up on the page.
so in one case it my get a drop down menu and in another case it may get an input box. the other very important piece is that this must be setup so that I can give the end result out as a module that can be installed and not worrry that it won't show up if someone upgrades there magento
that said does it still make sense to do this all in the xml file ?
It seems to me that your code is overriding a core Magento module in order to achieve what could be easily done in the layout xml configuration. I would strongly recommend the follwing:
Use the built-in configuration mechanisms (e.g. layout xml - read Alan's excellent tutorial here) instead of writing code whenever possible.
Don't override the core code
if you must change the behaviour of the core code, use an Observer rather than Rewrite/Override
if you absolutely must Override, always call parent::whatever()
For example, if you create a <module>.xml layout file in your theme (app/design/frontend/default/<theme>/layout), you could use the following code:
<catalog_product_view>
<reference name="content">
<block type="module/block" name"my_block_name_here" template="module/test.phtml"/>
</reference>
</catalog_product_view>
You would then need to use a getChildHtml('my_block_name_here'); call within your phtml to position the block.
So unless there is other functionality happening inside your _prepareLayout, there's no need to override the core, or even to override the default catalog.xml.
EDIT (small edit above)
So now in your Block (I would recommend that you call it Namespace_Module_Block_Product_Customattributes or something like that), you are not overriding the core Product_View block, but merely processing your logic for what html widgets to use to render your custom attributes. Leave the rest of the tier prices, add to cart, other generic product block code, etc to Magento to work out.
If you are worried about the upgrade path for your module's users, you should definitely NOT be overriding core code. Use the configuration approach and very selectively introduce code that "plays nice" with the system rather than try to boss it around with overrides.
I took a look at a stock Magento install of CE 1.4.1, and unmodified the _prepareLayout method is called six times when loading the URL
http://magento.example.com/catalog/product/view/id/46
That's because the class is instantiated six times. So that's the correct behavior.
As for the vanishing element, I can'y say for sure, but your override to _prepareLayout doesn't appear to either
Do the same things as Mage_Catalog_Block_Product_View::_prepareLayout
Call parent::_prepareLayout();
When you override a class in a Magento you're replacing an existing class with your own. If you change a method, you're responsible for that old code being run.
It's not clear what you're trying to accomplish here. You should consider breaking your problem down into smaller problems, and then posting one (or more) "I tried X, expected Y, and got Z" type questions. As written no one's going to be able to answer your question.

Resources