As I said in a different post, I'm trying to adapt an open source intranet to my needs. One of the things I'm trying to do is make the intranet look for the view templates in a different folder than the default ($customViewPath and $defaultViewPath, from now on).
I'm totally unexperienced with Zend Framework and I'm having a hard time figuring some things out, but with this one I think I have come to a dead end.
What I'm trying is to add my custom path for the view templates by using $view->addScriptPath($customViewPath) in the bootstrap. Actually, it works, but only if the view file doesn't exist in $defaultViewPath. What I want is just the opposite: if a custom file doesn't exist in $customViewPath, load the default view from $defaultViewPath.
If I print getScriptPaths(), I get array($defaultViewPath, $customViewPath). That is, somewhere in the life cycle of the script, $defaultViewPath is added to the list of view paths with a higher priority than my custom path. I can't find where this happens, and don't think it is in every module controller.
Also, I know I must move my piece of code $view->addScriptPath($customViewPath) somewhere outside the bootstrap, since the custom path is module related, but I can't access the module name from my bootstrap because request hasn't been initiated yet. I guess I could change that, but I would like to keep the original behaviour as much as possible.
I have read every bit of info about addScriptPath(), setScriptPath(), getScriptPaths() I could understand, but still have no idea on how to apply that to my case. Any idea will be welcome.
I'm aware I should provide more information about the application, but my lack of experience makes me not know what else can be necessary. Please feel free to ask for anything that could make my problem clearer.
The code of the application can be downloaded from its web. I just don't post the link here so that it doesn't look like spam.
Edit:
I'm sorry to insist on this topic, but the more I learn about ZF the more puzzled I am with the issue.
I have traced the stack of view paths, and somewhere between my plugin preDispatch() and the action preDispatch() functions, the default path (the one I'm trying to override) is pushed into the stack.
The only thing I can think of is some other plugin is being executed after mine. I have tried to give my plugin a very high execution order number, but still nothing.
I'm not exaggerating if I say that I have spent at least two weeks on this issue (tho I can't afford to spend more time on this at work, I am spendin a lot at home), I have read everything I could put my hands on about the dispatch cycle, but I don't know what to try next.
Just in case I may be right, is there any way to list from an action what plugins are being executed and their order?
Basically you have reverse the order of the path stack.
Try:
protected function _initView()
{
//Initialize view
$view = new Zend_View();
//reset script path stack with custom view path
$view->setScriptPath($customViewPath);
//add default path back to path stack
$view->addScriptPath($defaultViewPath);
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer');
$viewRenderer->setView($view);
//Return it, so that it can be stored by the bootstrap
return $view;
}
this should accomplish pretty much what you are looking for.
Related
I'm kind of new to Prestashop and I decided to practice on a project that's completed already (Prestashop 1.6.1.18). The thing is the project is pretty large and sometimes I get lost in the folder structure. I come from Codeigniter and Symfony and thought that might have been useful thinking Prestashop too had a similar URL->Controller->View mechanics but so far I've been going on for a while now trying to find the controller (and controller function) which handles this specific URL:
http://localhost/content/discount-products
I would appreciate some insight on how URL end points make their way to a function in a controller. Are they registered somewhere (Routes.php in Codeigniter, config files in Symfony). Should I be able to now this from that URL alone?
Thanx
Use this code on hookDisplayHeader
p($this->context->controller);
This code gives you all information about current controller on both BO and FO
I'm writing this small blogging platform in Laravel 4.1, for learning purpose. My first obstacle is, I don't know where the global data (ie. dynamic blog settings, plugin and theme array) should be put, so that I can access them from anywhere (similar to how $wpdb in WordPress works - we only need global $wpdb; to access it).
Of course $GLOBALS works, but we know that it's evil and should be avoided. Also, I'd like everything to be as Laravel'y as possible.
Have tried:
App::bind('settings', []); // error
App::instance('settings', []); // how to populate and retrieve it back?
Any ideas? Thanks in advance.
If this is not something you need to keep between sessions, you can use:
Config::set('myglobals.name', 'An Phan');
And then
var_dump( Config::get('myglobals.name') );
But you also have to think a bit and think why would you need globals in the first place. Take a look at this: http://c2.com/cgi/wiki?GlobalVariablesAreBad.
EDIT
This is not a workaround, this is something Laravel provides out of the box and you can use yourself. Usually the purpose of Config would be having configuration files to be used by your application, but sometimes you just need to change those values during the request, that's why Laravel provides also a set() method.
Unfortunately WP has an old codebase and if you are trying do things the way WP does things, you're goind the in wrong path.
What would be the Laravel way depends on what you're trying to accomplish with your project, so you'll have to tell a little bit more about it.
The mindset to start with is: "I don't need globals" and when you get to a point where a global is needed, you ask yourself "how do I do this without using a global?".
Usually, you just need global values if you have settings to store. If it's something that you have to use to set a state during a request, you need to use objects. You can have global objects in Laravel, you can have singletons (objects that has only one instance in the whole application), you can create properties objects:
class SidebarProperties {
private $width;
public function __construct($width)
{
$this->width = $width
}
public getWidth()
{
return $this->width;
}
}
So you have an uncountable number of way to not use globals, you just have to think about your project and pick the one is best at that moment.
Well, global in a Laravel context means relative to Application, if you are not writing anything that "lives" outside of Application context.
There are couple of ways in which you can make you data available to application. But first, you have to make decision what kind of "globals" do you need ?
First and most important rule is that any change that you make besides Application specific folder structure, has to be told to composer.
Second, without making any changes, Laravel has default locations for most important parts of any "ordinary" web application.
Application folder structure is pretty self descriptive, but in short:
Configurations belongs to app/config
Models to app/models
Views to app/views
Controllers to app/controllers
Database to app/database
Routes to app/routes.php
If you follow this basic structure, you can create amazing web-apps. these folders and files are already namespaced and classes inside them are auto resolved. In you example you were trying to bind something to application, which is redundant in you case. Bindings to container are used in cases when you want to add some new classes and functionality to existing structure.
In short:
create you first route in routes.php like this:
Route::get("GET",function(){
return "my first route";
})
And from that point follow basic MVC flow, which is no different then most frameworks. Laravel is talking to you, just open you ears :)
And if you stack, just ask here, somebody will help.
Really not sure if the title of the question suits the question overall. But here goes.
What I have currently is an existing SaaS project. That we want to roll out a new template over time. Think of how google introduces new features. Or some other sites might with "Try our new Beta Version".. type of thing. Well we want to do the same, and then we will eventually phase out the old look and feel.
With that, this application is built on top of Zend Framework, so looking through docs I can figure out how to override the template on a given controller. But what I want to basically do, is likely going to make use of the sessions. If it exists, use this template. If not, use the old one.
Is it possible to override the default template in such a fashion? Right now for example, the default loaded file, is "tops.phtml" if the session exists I'd like to load "tops_v2.phtml" for example. So it can use that as the template instead of "tops.phtml" when the session is found.
Zend Framework 1.x solution:
You can disable ViewRenderer plugin in the action, and choose template manually:
public function indexAction(){
$this->_helper->viewRenderer->setNoRender(true);
echo $this->view->render("path/to/template/template.phtml");
}
I think that layouts are the thing you probably want to use, as was briefly touched on by Richie. Based on the question, I'm guessing you aren't already using them. Ultimately you can design a layout that defines the overall website look and then each of your action templates will only then render a fragment of the page (which will be dynamically placed in the content portion of the layout).
Using whatever logic you choose, you can then assign one of any number of layouts to be used on a given page load and of course you could store this as a user preference or something.
I'm pretty new to php and Zend in general, so I'll try to be as clear as I can. I have taken over a complete web project written in PHP.
In the main layout is script partials/menu.phtml, where is a list of few pages. And I wanted to add another one (called pricelist). I created a new pricelist.phtml file in directory info/ with other pages leading from this menu (in view).
Then in InfoController I created new public function pricelistAction() which includes
$this->view->headTitle()->append('Info');
$this->view->headTitle()->append('Pricelist');
Nothing is written in model. When I run localhost and click Info - Pricelist, the page is not found. I have no clue what I might have forgotten or what is wrong. I'm stuck on this for several days and starting to be desperate. I really appreciate any help. Thank you very much!
Two things:
Make sure there is a proper route in your module.config file that causes this action to be triggered. /baseroute/:action or /baseroute/pricelist...something like that
There are several ways of loading views/templates: Some developers require you to set new view files up explicitly in the view_manage=>template_map section of your module.config file, rather than let zend handle it automatically.
It's hard to guess without seeing your code/directory structure but this is where I would start.
I am trying to use the MVC architecture of sugarcrm to add a new action and with that a new view.
I have managed to create a controller with the action and also a class view, the only thing I can't figure out is how to create a simple html page.
Do I really have to use the metada way of sugarcrm?? I just want a simple form with two or three fields.
Are there alternatives to the metadata or do I really have to use it to create my simple page????
You will want to stay within the metadata framework to create your new page if possible. However, once you are in the view controllers, you can echo out anything you wish and still stay "upgrade safe" by overriding the display() function. But, the right way to do what you are wanting to accomplish above is to not only override the display() function but also create a new tpl file (custom/modules//tpls/view.tpl) and then perform whatever you need to perform PHP wise and then assign the variables via the smarty templating engine (I know this sounds complicated - but it's not. It's actually pretty straightforward once you understand Smarty).
One other thing - make sure you are doing all of this (including your controllers and view files) in the custom/modules directory. As this will also keep things upgrade safe. And keep you free from all kinds of headaches in the future. :)
Here is a link to the SugarCRM Developer's Guide online and also a link to their Developer's website. SugarCRM has a pretty good community of developers on the forums so feel free to ask questions there as well.
Developer's Guide:
http://developers.sugarcrm.com/docs/OS/5.2/-docs-Developer_Guides-Developer_Guide_5.2-toc.html
Developer's Site:
http://developers.sugarcrm.com/
Hope this all helps!
Try to do following:
create a new module
put your page into custom/modules/
using URL index.php?module=&action= (without php extension, of course) you can access to your page.
If you'd like to have different action name and page name then you should add the file action_file_map.php
into your module directory and specify inside the mapping:
$action_file_map['action_name'] = 'path_to_your_page';
Note that action_name must be all lowercase - the SugarController won't be able to to match mixed-case actions (true as of SugarCRM 6.1.2).