How to cache layout content in Zend Framework - zend-framework

How would you implement caching of the layout content in Zend Framework?
In the layout.phtml I do: $this->layout->content and I want the content of this variable to be cached. The other widgets from the layout are real time (or cached other way).
The best bets are:
static cache (the fastest)
page cache
My pages already have unique page id (canonical), so it could be used as page cache tag.
Potentially looks like I have to overload __get property of the layout.
I'm trying to do something like the layout of SO (user panel at the top, rest cached for all).
I assume, site should work without JavaScript.

You might want to have a look at the Front Controller Cache plugin weierophinney describes. The problem probably is that you don't want the script to stop on cache hit. So you don't exit; the the script, you could work with $request->setDispatched(true) within the plugin. (You'd need a new request-object for every different cacheable).
Another approach could be that you don't use the dispatchLoopStartup but the preDispatch in your plugin and reset the dispatching there.
They way to go actually depends on how you load all the other stuff (be it cached or not). (E.g. the ActionStack pushes a new request to the dispatcher).

Related

Cross-domain navigation within Blogger without Javascript

The setup: I have a Blogger blog set up on a domain name as blog.mydomain.com. The main site site at mydomain.com is running Umbraco CMS.
The problem: I need to have the navigation from the CMS transported to Blogger somehow, so that making a change on the main website doesn't require the extra step of modifying the navigation inside Blogger.
Generating the navigation data on the CMS side in what ever format it needs to be (XML, unordered list, JSON, etc) is not a problem. The problem is getting the data from Umbraco to Blogger after it is generated.
I'm not yet willing to use Javascript, as this would seriously impair the website for users browsing without Javascript. (Too bad because AJAX would be a very workable solution.)
I've tossed around the idea of using an iFrame. How would this work for a navigation system including sub-menus? Creating and deleting multiple iframes is out of the picture, since I don't want to use Javascript. I could use one large iframe to allow for the sub-menus, but then it would cover content at the top of the content area, rendering it unclickable.
I'm thinking about how you could do this, but while I do - in this day-and-age javascript has become very common. Most users are going to have it, and those with it disabled really shouldn't be on the web. Is this the only reason you don't want to use javascript? Around 2% according to YDN have js disabled, and that's lower from other countries. As time goes on that 2% should get lower, I don't see that as an issue. However if you absolutely can't use javascript, I'll keep thinking. I might have an idea, I'll need to test it though.
It's not possible to use IFrame, cause of same origin policy. Both sites are on different domains, when user click menu item inside IFrame, there is no way to call parent window.
There are few ways how this can be done.
1) Javascript solution. Use json rpc, or another cross-domain calls. Load menu from your CMS and render it. Yes, this requires javsascript, but, seriously, show me the site, which does not use javascript.
2) Direct server communication.
Is it possible to perform http call from blogger ? If so, just perform http call to your CMS from Blogger, get data and render it.
3) Mixed flash/javascript solution. Flash can perform http call regardless of same origin policy. Get data with flash, use ExternalInterface to call Javascript function to render data.
There is no another way to do it. I suggest you to use javascript solution
You could build an HTML skeleton of empty ULs in Blogger (the max that you might need) to hold your navigation contents, and then link to an Umbraco-generated external stylesheet.
This stylesheet could fill those LIs with CSS generated content using the :before and :after pseudo-elements, and hiding unused LIs with CSS display: none.
An example of this is at: http://jsfiddle.net/5bXja/1/
This works in IE8+ so depending on your clients, this may-or-may-not be more widely supported than Javascript. Likely not. ;-)

Why no Zend_Layout helper or codebehind? And best way to

I was just wondering why no code-behind or helpers were made to work with layouts? I have stuff I want to display in my layouts without having to set it up in a placeholder for every single controller.
I was also wanted to know what is the best way to persist a display-once "success-message" across many pages. For example, a user fills out a form and when it is submitted correctly they are redirected to another page. I want the user to see a success message on that other page. Is there some sort of provision in Zend Framework that makes this easier?
Well for the messages you can use the Flash Messenger helper
As far as setting up the place holders you could use a base controller and set these up in the init method overriding on descendents when necessary.

Setting active page when Zend_Navigation is cached?

Update - Please see update below.
I'm attempting to improve the performance of our ZF based CMS, and am trying out caching the Zend_Navigation object I create with the menu structure. Caching the object means I can't set the current page to active, or I'll have a copy of the menu in the cache for every page.
To allow caching of the structure, regardless of current page, I've moved highlighting of the current page in the menu to jQuery, which is working well. Then I noticed that the Breadcrumb_Helper (which uses the same Zend_Navigation object as the menu) wasn't displaying anything - obviously because I haven't got a page set to active.
Given I know the id of the page, is there a way to get inside the Zend_Navigation object to set that particular one to active?
Ideally I'd like to do something like:
$nav->findOneBy("id", $currentPageId)->setActive(true);
But there doesn't seem to be a way to access the pages in the object like this. Looking at the code, using findOneBy to get the current page, then removePage to remove it, then setting the collected one to active, and using addPage to put the collected, updated one back in might be an option, but rather convoluted.
The other option is just to cache the array I use to construct the Zend_Navigation object, which would be easier to set the current page to active, after getting the base array from the cache.
(I should point out that all the pages in the cms just have urls like /privacy, /about-us, and are routed to a default frontend module, controller and action, so there is no controllrt/action in the url to allow ZF to work out where it is.)
Update:
Ahem.... Seems like the code I suggested did actually work, and can actually be done slightly more simply using the magic finder methods...:
$nav->findOneById($currentPageId)->setActive(true);
As noted above, this does indeed work:
$nav->findOneById($currentPageId)->setActive(true);

How to add styles dynamically from layout folder of zend application

My all styles are located behind the root under application layout folder. I don't want to keep my styleS in public folder.
How can I read them dynamically in my layout using below commands?
$styleFile = "greenish.css"; // from database
$this->headLink()->appendStylesheet(APPLICATION_PATH . 'modules/frontManagement/layouts/styles/'.$styleFile);
Any Idea?
If you want to avoid inline styling and only use headlink() but deliver content that is tucked safely away outside the web root or in a db, then it sounds like you'll have to headLink() to a dynamic server-side script that accepts the customer identifier and then delivers that customer-specific CSS, complete with mime-type headers.
With clever cache headers and url naming, you might even be able to get this to cache on the browser side, like you'd get with static, totally public CSS resources.
But I'll tell ya, it all sounds like overkill to me. Who cares if all the other styles are 'accessible' as long as you deliver only stylesheet_XXX.css to customer 'XXX'? Still, if it's your requirement, then I think you can manage it with the approach above.
Why wouldn't you want to keep your styles/scripts in the public folder? That's where you're supposed to keep them because, well, because their public resources.
Even if you kept them somewhere else, you'd still have to read it and apply the styles to your page. Which means you can't actually hide it (if that's your intention)
I think you want the HeadStyle view helper which includes the style sheet inline in the document head. The basic usage is something like this:
$styleFile = "greenish.css"; // from database
$style = file_get_contents(APPLICATION_PATH . 'modules/frontManagement/layouts/styles/'.$styleFile);
$this->headStyle()->appendStyle($style);

Go to a new page, but still have GWT variables?

In GWT, I would like to do something like a form submission that takes me to a new page, with new style sheet and new static elements, and when I get there, be able to extract the values of GWT variables still in GWT. In other words, I want to do most of the form processing on the client side instead of sending it to a servlet to be processed and sent back. Is that possible? Would FormPanel allow me to do that? How do I access the contents of the form fields in GWT on the new page?
I'm not sure I'm getting the right picture here, but I see several possibilities:
Pass the variables in the url like example.com/myform#create/param1/param2 or any other format you want, then read it using the History class
Use something like this - create an iframe from GWT (maybe put it in Lightbox or something similar), populate it the way you want using the current state of the app, and when the user is finished, he'll just close the (Lightbox) frame and get back to the main application
You could also pass around data in a "hidden" way (no visible data in the url or even through POST) using the window.name hack - there's even a sample implementation for GWT to get you started
ATM, I prefer the second option, since it goes best with the whole no refresh, same page, one app, GWT thing :) That is, unless I'm getting the wrong picture and you want to do something else.
GWT is really meant to be used for the whole application, where "pages" are replaced by application state and URL fragments, and "form submission" is replaced by AJAX calls.
If you want to validate form fields, this can easily be done with regular JS or a library like jQuery.
I'm not sure it I get you right either, but for what I'm receiving, having a new page to process the form is not the optimal design. The reason been that you might have to write different GWT app for that which mean overheads, and creating new window (or tab) will move the user's attention away from where they are. Why not using another page WITHIN gwt to process the form with tab panel or hidden panel?