Created
June 30, 2011 11:41
-
-
Save dzuelke/1056065 to your computer and use it in GitHub Desktop.
Simple prototype of Edge Site Includes support for slots in Agavi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 <[email protected]> | |
+ */ | |
+ public function generateEsiUrl(AgaviRouting $ro, AgaviRequestDataHolder $arguments = null) | |
+ { | |
+ return null; | |
+ } | |
+ | |
+ /** | |
* Manually register validators for this action. | |
* | |
* @author Sean Kerr <[email protected]> | |
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 <[email protected]> | |
+ */ | |
+ 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