Skip to content

Instantly share code, notes, and snippets.

@dzuelke
Created June 30, 2011 11:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dzuelke/1056065 to your computer and use it in GitHub Desktop.
Save dzuelke/1056065 to your computer and use it in GitHub Desktop.
Simple prototype of Edge Site Includes support for slots in Agavi
Index: samples/app/modules/Default/actions/Widgets/MenuAction.class.php
===================================================================
--- samples/app/modules/Default/actions/Widgets/MenuAction.class.php (revision 4758)
+++ samples/app/modules/Default/actions/Widgets/MenuAction.class.php (working copy)
@@ -71,6 +71,11 @@
return 'Success';
}
+ public function generateEsiUrl(AgaviRouting $ro, AgaviRequestDataHolder $rd = null)
+ {
+ return $ro->gen('esi.mainnav', array(), 'esi');
+ }
+
public function isSimple()
{
return true;
Index: samples/app/config/routing.xml
===================================================================
--- samples/app/config/routing.xml (revision 4758)
+++ samples/app/config/routing.xml (working copy)
@@ -55,6 +55,10 @@
<!-- The last route in case the input URL is just "/". -->
<route name="index" pattern="^/$" module="%actions.default_module%" action="%actions.default_action%" />
+ <route name="esi" pattern="^/esi">
+ <route name=".mainnav" pattern="^/mainnav$" module="Default" action="Widgets.Menu" />
+ </route>
+
<!-- If no route matched here, the 404 action will be used. You could change that behavior by setting the last route above to use an empty pattern. -->
</routes>
</ae:configuration>
Index: samples/app/config/factories.xml
===================================================================
--- samples/app/config/factories.xml (revision 4758)
+++ samples/app/config/factories.xml (working copy)
@@ -21,7 +21,14 @@
<response class="AgaviWebResponse" />
- <routing class="AgaviWebRouting" />
+ <routing class="AgaviWebRouting">
+ <ae:parameter name="gen_options_presets">
+ <ae:parameter name="esi">
+ <ae:parameter name="separator"><![CDATA[&]]></ae:parameter>
+ <ae:parameter name="relative">false</ae:parameter>
+ </ae:parameter>
+ </ae:parameter>
+ </routing>
<security_filter class="AgaviSecurityFilter" />
Index: src/action/AgaviAction.class.php
===================================================================
--- src/action/AgaviAction.class.php (revision 4758)
+++ src/action/AgaviAction.class.php (working copy)
@@ -146,6 +146,29 @@
}
/**
+ * Generates a URL that can be used to perform an Edge Site Include (ESI) for
+ * this Action. Only arguments explicitly passed to this execution container
+ * are available in the request data holder; the request data itself is not
+ * available to avoid side-effects from the current request that would not be
+ * present in the standalone ESI request.
+ *
+ * @param AgaviRouting The routing object, for convenience.
+ * @param AgaviRequestDataHolder The arguments of this container, or null
+ * if no arguments have been passed.
+ *
+ * @return string A string with the absolute URL that invokes this action
+ * as a stand-alone operation, or null if no ESI directive
+ * should be generated (the Action is run as usual then).
+ *
+ * @since 1.1.0
+ * @author David Zülke <david.zuelke@bitextender.com>
+ */
+ public function generateEsiUrl(AgaviRouting $ro, AgaviRequestDataHolder $arguments = null)
+ {
+ return null;
+ }
+
+ /**
* Manually register validators for this action.
*
* @author Sean Kerr <skerr@mojavi.org>
Index: src/filter/AgaviExecutionFilter.class.php
===================================================================
--- src/filter/AgaviExecutionFilter.class.php (revision 4758)
+++ src/filter/AgaviExecutionFilter.class.php (working copy)
@@ -324,6 +324,23 @@
}
/**
+ * Generates an include statement for the given URL, usually an ESI directive.
+ *
+ * @param string The URL to include.
+ *
+ * @return AgaviResponse The response with all necessary metadata.
+ *
+ * @since 1.1.0
+ * @author David Zülke <david.zuelke@bitextender.com>
+ */
+ public function generateEsiFragment($url)
+ {
+ $response = $this->getContext()->createInstanceFor('response');
+ $response->setContent('<esi:include xmlns:esi="http://www.edge-delivery.org/esi/1.0" src="' . htmlspecialchars($url) . '" />');
+ return $response;
+ }
+
+ /**
* Execute this filter.
*
* @param AgaviFilterChain The filter chain.
@@ -354,6 +371,7 @@
$actionInstance = $container->getActionInstance();
$request = $this->context->getRequest();
+ $routing = $this->context->getRouting();
$isCacheable = false;
$cachingDotXml = AgaviToolkit::evaluateModuleDirective(
@@ -619,11 +637,15 @@
// $lm->log('Loading cached slot "' . $slotName . '"...');
$slotResponse = $viewCache['slots'][$layerName][$slotName];
} else {
- // $lm->log('Running slot "' . $slotName . '"...');
- $slotResponse = $slotContainer->execute();
- if($isCacheable && !$isViewCached && isset($otConfig['layers'][$layerName]) && is_array($otConfig['layers'][$layerName]) && in_array($slotName, $otConfig['layers'][$layerName])) {
- // $lm->log('Adding response of slot "' . $slotName . '" to cache...');
- $viewCache['slots'][$layerName][$slotName] = $slotResponse;
+ if(($url = $slotContainer->getActionInstance()->generateEsiUrl($routing, $slotContainer->getArguments())) !== null) {
+ $slotResponse = $this->generateEsiFragment($url);
+ } else {
+ // $lm->log('Running slot "' . $slotName . '"...');
+ $slotResponse = $slotContainer->execute();
+ if($isCacheable && !$isViewCached && isset($otConfig['layers'][$layerName]) && is_array($otConfig['layers'][$layerName]) && in_array($slotName, $otConfig['layers'][$layerName])) {
+ // $lm->log('Adding response of slot "' . $slotName . '" to cache...');
+ $viewCache['slots'][$layerName][$slotName] = $slotResponse;
+ }
}
}
// set the presentation data as a template attribute
Index: src/controller/AgaviExecutionContainer.class.php
===================================================================
--- src/controller/AgaviExecutionContainer.class.php (revision 4758)
+++ src/controller/AgaviExecutionContainer.class.php (working copy)
@@ -252,29 +252,12 @@
$controller->countExecution();
$moduleName = $this->getModuleName();
- $actionName = $this->getActionName();
-
- try {
- // TODO: cleanup and merge with createActionInstance once Exceptions have been cleaned up and specced properly so that the two error conditions can be told apart
- if(false === $controller->checkActionFile($moduleName, $actionName)) {
- $this->setNext($this->createSystemActionForwardContainer('error_404'));
- return $this->proceed();
- }
-
- $this->actionInstance = $controller->createActionInstance($moduleName, $actionName);
- } catch(AgaviDisabledModuleException $e) {
- $this->setNext($this->createSystemActionForwardContainer('module_disabled'));
- return $this->proceed();
- }
-
-
- // initialize the action
- $this->actionInstance->initialize($this);
+ $actionInstance = $this->getActionInstance();
// copy and merge request data as required
$this->initRequestData();
- if($this->actionInstance->isSimple()) {
+ if($actionInstance->isSimple()) {
// run the execution filter, without a proper chain
$controller->getFilter('execution')->execute(new AgaviFilterChain(), $this);
} else {
@@ -784,6 +767,29 @@
*/
public function getActionInstance()
{
+ if($this->actionInstance === null) {
+ $controller = $this->context->getController();
+
+ $moduleName = $this->getModuleName();
+ $actionName = $this->getActionName();
+
+ try {
+ // TODO: cleanup and merge with createActionInstance once Exceptions have been cleaned up and specced properly so that the two error conditions can be told apart
+ if(false === $controller->checkActionFile($moduleName, $actionName)) {
+ $this->setNext($this->createSystemActionForwardContainer('error_404'));
+ return $this->proceed();
+ }
+
+ $this->actionInstance = $controller->createActionInstance($moduleName, $actionName);
+ } catch(AgaviDisabledModuleException $e) {
+ $this->setNext($this->createSystemActionForwardContainer('module_disabled'));
+ return $this->proceed();
+ }
+
+ // initialize the action
+ $this->actionInstance->initialize($this);
+ }
+
return $this->actionInstance;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment