What is the best practice for disabling a cache request from the Full Page Cache (FPC) in magento (enterprise) - magento

I wish to remove the following setting:
<cms>enterprise_pagecache/processor_default</cms>
... from the config.xml of the core / Enterprise / PageCache / config.xml file so that the home page will not be cached, (because we have a complicated custom store switch in place).
Since this value is not stored in core_config_data I am unsure of the best way to override the out of the box value. The comments above the line in the core file do hint that it is not actually bad practice to edit this file, however, can I open this to the community to see what they think?
PS = This is a multi website setup with a custom store switcher.

Hole punching is what it sounds like you may need.
Add a etc/cache.xml file with a <config> root to your module. (see Enterprise/PageCache/etc/cache.xml). Choose a unique [placeholder] name.
The placeholders/[placeholder]/block node value must match the class-id of your custom dynamic block, e.g. mymodule/custom
The placeholders/[placeholder]/container node value is the class to generate the content dynamically and handle block level caching
The placeholders/[placeholder]/placeholder node value is a unique string to mark the dynamic parts in the cached page
placeholders/[placeholder]/cache_lifetime is ignored, specify a block cache lifetime in the container’s _saveCache() method if needed
Implement the container class and extends Enterprise_PageCache_Model_Container_Abstract. Use _renderBlock() to return the dynamic content.
Implement the _getCacheId() method in the container to enable the block level caching. Use cookie values instead of model ids (lower cost).
One last note: You DON’T have the full Magento App at your disposal when _renderBlock() is called. Be as conservative as possible.
SOURCE: http://tweetorials.tumblr.com/post/10160075026/ee-full-page-cache-hole-punching

Related

User specific content in TYPO3 and caching

How to show not cached fe_user data in TYPO3? According to Prevent to Cache Login Information.
The ViewHelper sets $GLOBALS['TSFE']->no_cache = 1 if the user logged in. Is there a better way? Because not the whole page should not be cached, only some parts of it.
Unfortunately this is not possible.
The best way is, you render the not cached fe_user data with a AJAX called eID or TypeNum and the whole page is completly cached.
like this one:
http://www.typo3-tutorials.org/cms/typo3-und-ajax-wie-geht-das.html
your example code disabled cache for the complete page. but you only need to disable cache for the part where you display the user specific data. As you can except any part from caching you need to select whether to cache only
one content element (especially for plugins this is standard behaviour: just declare your plugin as uncachable in your ext_localconf.php)
one column (make sure you use a COA_INT (or other uncached object) in your typoscript)
one viewhelper (make your viewhelper uncachable [1] or use the v:render.uncache() VH from EXT:vhs)
[1]
as a viewhelper is derived from AbstractConditionViewHelper, which uses the Compilable Interface, which caches the result, the compile() method from AbstractConditionViewHelper must be rewritten and return the constant
\TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler::SHOULD_GENERATE_VIEWHELPER_INVOCATION
like this:
public function compile(
$argumentsVariableName,
$renderChildrenClosureVariableName,
&$initializationPhpCode,
\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode,
\TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler
) {
parent::compile(
$argumentsVariableName,
$renderChildrenClosureVariableName,
$initializationPhpCode,
$syntaxTreeNode,
$templateCompiler
);
return \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler::SHOULD_GENERATE_VIEWHELPER_INVOCATION;
}

Joomla progressive cache doesn't handle modules with variable output

I have a module which allows the user to choose a category, which is then used for filtering the component's output. So when the user first clicks on the menu item, the view shows items from all categories, then as they click on the module, a param such as &catid=69 etc. is added to the url and used to filter the items displayed.
A system plugin complements the behaviour by registering the extra catid param i.e.
$registeredurlparams->catid = 'INT';
$app->set('registeredurlparams', $registeredurlparams);
The module uses the category id to create the cache id, and shows the top-level categories + the subcategories of the category that was chosen.
This works fine with both conservative cache enabled in the system configuration and the System Cache plugin enabled.
My concern is that I cannot get it to work with progressive cache: even though the component output is cached correctly, the module doesn't get updated (so I never see the subcategories).
Eventually I plan to make the extension available on the JED, and I'd like to be compatible with all possible cache configurations. Is there any possibility to force the progressive cache to add the parameters I want to the cache id?
Workarounds such as sending the full category tree and doing it with ajax will not be accepted.
One thing you could look at is ContentModelArticle in the back end. You will notice that cleanCache()
forcibly clears the content modules that could be impacted by a save or create.
protected function cleanCache($group = null, $client_id = 0)
{
parent::cleanCache('com_content');
parent::cleanCache('mod_articles_archive');
parent::cleanCache('mod_articles_categories');
parent::cleanCache('mod_articles_category');
parent::cleanCache('mod_articles_latest');
parent::cleanCache('mod_articles_news');
parent::cleanCache('mod_articles_popular');
}
I've always thought this was a sledge hammer/kludge since it doesn't let the webmaster control whether or not to do this, but you could do something along the lines of making a custom cleanCache() for your model.

How to update specific cached route?

I am running a Symfony2 app and I have a question about caching.
There is a comment on an answer here in SO that says:
you could create a command that only updates this one cached route. or
maybe consider using a kernel event listener that newly registers the
route on every request if you can afford the performance impact.
How could I update only this one cached route?
Where are cached routes stored?
The cache classes for url matching/generation can be found in app/cache/environment and are called appEnvironmentUrlGenerator.php and appEnvironmentUrlGenerator.php with "environment" being one of dev,prod, .. etc.
API reference:
http://api.symfony.com/2.3/Symfony/Component/Routing/Matcher/UrlMatcher.html
http://api.symfony.com/2.3/Symfony/Component/Routing/Generator/UrlGenerator.html
How does it work?
The router service receives a url-matcher and a url-generator when being constructed. Those are then being used inside the match() and generate() methods of the router.
https://github.com/symfony/symfony/blob/2.3/src/Symfony/Component/Routing/Router.php
For warming up the cache the RoutingCacheWarmer uses the router's warmUp() method (if it implements WarmableInterface).
Everything written by nifr is true, but doesn't really help you.
Symfony's built in router designed to support 'static' routes, so on the first cache warmup the routes will be generated and cached. If you check the mentioned cache files you will see that the routes saved in a static private variable.
There is no simple way to update a route (or change routes).
Using Symfony2 CMF
This a bit complex solution for your simple problem: http://symfony.com/doc/master/cmf/index.html
Clearing (invalidating) the cache
If you check the CacheClearCommand you will see that the implementation is quite complex. Some suggest to delete the whole cache dir, which I don't recommend, it is quite heavy and makes your site hang on until the cache is regenerated (even you can get exceptions of missing files / and logged out users if the sessions saved under the cache folder)
Calling the cache_warmer warmup has no effect if the cache already delegated.
If you just remove the two related cache file and then call the warmUp on the router would be a better solution, but also not nice one..
$cacheDir = $this->container->getParameter("kernel.cache_dir");
// Delete routing cache files
$filesystem = $this->container->get('filesystem');
$finder = new Finder();
/** #var File $file */
foreach ($finder->files()->depth('== 0')->in($cacheDir) as $file) {
if (preg_match('/UrlGenerator|UrlMatcher/', $file->getFilename()) == 1) {
$filesystem->remove($file->getRealpath());
}
}
$router = $this->container->get('router');
$router->warmUp($cacheDir);
Override the default Router class
As of 2.8 the Router class is defined with a parameter router.class
See here: https://github.com/symfony/framework-bundle/blob/v2.8.2/Resources/config/routing.xml#L63
Add something like this to your config.yml
parameters:
router.class: "My\Fancy\Router"
You can implement your own Router class, extending the original Router, and also you will need to extend the UrlMatcher and UrlGenerator classes to call the parent implementation and add your own routes to match against / generate with. This way you don't need to refresh the cache, because you can add your routes dynamically.
Note: I'm not sure if you can rely on this on long term, if you check master, the definition has changed, the parameter is not there anymore:
https://github.com/symfony/framework-bundle/blob/master/Resources/config/routing.xml#L54

How to build CodeIgniter URL with hierarchy?

I know this doesn't exactly match the form of www.example.com/class/function/ID/, but what I want to display to the user would make more sense.
This is what I would like to do:
www.example.com/project/id/item/item_id/
So, an example would be:
www.example.com/project/5/item/198237/
And this would be the behavior:
www.example.com/project/ --> This would show a list of projects (current implementation)
www.example.com/project/5/ --> This would show a list of items on project 5 (current implementation)
www.example.com/project/5/item/ --> This wouldn't really mean anything different than the line above. (Is that bad?)
www.example.com/project/5/item/198237/ --> This would show details for item 198237.
So, each item is directly associated with one and only one project.
The only way I can think how to do this is to bloat the "project" controller and parse the various parameters and control ALL views from that "project" controller. I'd prefer not to do this, because the model and view for an "item" are truly separate from the model and view of a "project."
The only other solution (that I am currently implementing and don't prefer) is to have the following:
www.example.com/project/5/
www.example.com/item/198237/
Is there any way to build a hierarchical URL as I showed at the beginning without bloating the "project" controller?
There are 3 options, sorted by how practical they can be:
Use URI Routing. Define a regular expression that will use a specific controller/method combination for each URL.
Something like that could help you, in routes.php:
$route['project/'] = 'project/viewall';
$route['project/(.+)'] = 'project/view/$1';
$route['project/(.+)/item/'] = 'project/view/$1';
$route['project/(.+)/item/(.+)'] = 'item/view/$2';
That is, considering your controllers are item and project respectively. Also note that $n in the value corresponds to the part matched in the n-th parenthesis.
Use the same controller with (or without) redirection. I guess you already considered this.
Use redirection at a lower level, such as ModRewrite on Apache servers. You could come up with a rule similar to the one in routes.php. If you are already using such a method, it wouldn't be a bad idea to use that, but only if you are already using such a thing, and preferably, in the case of Apache, in the server configuration rather than an .htaccess file.
You can control all of these options using routes.php (found in the config folder). You can alternatively catch any of your URI segments using the URI class, as in $this->uri->segment(2). That is if you have the URL helper loaded. That you can load by default in the autoload.php file (also in the config folder).

Sitecore global url to specific url

Currently I am facing the following problem:
A website, which I have to make for a company, has different locations. But the content of a few pages is for all locations the same. Now I have created a global folder with the items for all the locations. But now I am facing the following problem: when accessing the global items from the website of a specific location I get the global url. But what I want is that the specific location url remains the same structure, for example:
Now it is www.url.com/global/subfolder/itemname
And what I want is www.url.com/location1/subfolder/itemname
Does anybody have any solution(s)/suggestion(s) for this problem?
Does anybody also have a solution for creating a menu to insert these global items but also to insert the location specific items?
Some more information about my Sitecore content structure
Global: contains the global items for alle locations
Corporate: the corporate website of the company
Location1: the website of location1
Location2: the website of location2
Adam Weber was right, cloning is your best solution:
Create your Global section, with all the child items you need
For each of your local sections, clone the global section and place it where you'd like it to appear within your local menu
If I understand you correctly, this is what I'd do. It might not be the prettiest solution. But it'll work.
You have your "data" items in /global/subfolder/itemname
then just create some templates, which are "dummy" pages, that only contain a link to the global item (and perhaps the few fields that could differ (perhaps contact email for the specifik location).
Then you make a sublayout that bascially jsut gets the referenced item and uses that instead of Sitecore.Context.Item.
Then create an instance of the "dummy" template in /location1/subfolder/itemname and reference it to /global/subfolder/itemname
That way you URLs will be correct and the data will be the same.
Another and probably smarter solution (if you have enabled proxies) is to create a proxy that takes
/global/subfolder/itemname as source and points to /location1/subfolder/ as target (or you could take /global/subfolder and check "include children".
Here is a Guide on how to use proxies in 5.3:
http://sdn.sitecore.net/Articles/Administration/Using%20Proxy%20Items%20in%205,-d-,3.aspx

Resources