Zend_Controller-ActionHelpers-ContextSwitch.xml 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect3 id="zend.controller.actionhelpers.contextswitch">
  4. <title>ContextSwitch and AjaxContext</title>
  5. <para>
  6. The <emphasis>ContextSwitch</emphasis> action helper is intended for
  7. facilitating returning different response formats on request.
  8. The <emphasis>AjaxContext</emphasis> helper is a specialized version of
  9. <emphasis>ContextSwitch</emphasis> that facilitates returning responses
  10. to XmlHttpRequests.
  11. </para>
  12. <para>
  13. To enable either one, you must provide hinting in your controller as to
  14. what actions can respond to which contexts. If an incoming request
  15. indicates a valid context for the given action, the helper will then:
  16. </para>
  17. <itemizedlist>
  18. <listitem>
  19. <para>
  20. Disable layouts, if enabled.
  21. </para>
  22. </listitem>
  23. <listitem>
  24. <para>
  25. Set an alternate view suffix, effectively requiring a separate
  26. view script for the context.
  27. </para>
  28. </listitem>
  29. <listitem>
  30. <para>
  31. Send appropriate response headers for the context desired.
  32. </para>
  33. </listitem>
  34. <listitem>
  35. <para>
  36. Optionally, call specified callbacks to setup the context and/or
  37. perform post-processing.
  38. </para>
  39. </listitem>
  40. </itemizedlist>
  41. <para>
  42. As an example, let's consider the following controller:
  43. </para>
  44. <programlisting language="php"><![CDATA[
  45. class NewsController extends Zend_Controller_Action
  46. {
  47. /**
  48. * Landing page; forwards to listAction()
  49. */
  50. public function indexAction()
  51. {
  52. $this->_forward('list');
  53. }
  54. /**
  55. * List news items
  56. */
  57. public function listAction()
  58. {
  59. }
  60. /**
  61. * View a news item
  62. */
  63. public function viewAction()
  64. {
  65. }
  66. }
  67. ]]></programlisting>
  68. <para>
  69. Let's say that we want the <methodname>listAction()</methodname> to also be
  70. available in an <acronym>XML</acronym> format. Instead of creating a different action, we
  71. can hint that it can return an <acronym>XML</acronym> response:
  72. </para>
  73. <programlisting language="php"><![CDATA[
  74. class NewsController extends Zend_Controller_Action
  75. {
  76. public function init()
  77. {
  78. $contextSwitch = $this->_helper->getHelper('contextSwitch');
  79. $contextSwitch->addActionContext('list', 'xml')
  80. ->initContext();
  81. }
  82. // ...
  83. }
  84. ]]></programlisting>
  85. <para>
  86. What this will do is:
  87. </para>
  88. <itemizedlist>
  89. <listitem>
  90. <para>
  91. Set the 'Content-Type' response header to '<filename>application/xml</filename>'.
  92. </para>
  93. </listitem>
  94. <listitem>
  95. <para>
  96. Change the view suffix to '<filename>xml.phtml</filename>' (or, if you use an
  97. alternate view suffix, 'xml.[your suffix]').
  98. </para>
  99. </listitem>
  100. </itemizedlist>
  101. <para>
  102. Now, you'll need to create a new view script, '<filename>news/list.xml.phtml</filename>',
  103. which will create and render the <acronym>XML</acronym>.
  104. </para>
  105. <para>
  106. To determine if a request should initiate a context switch, the helper
  107. checks for a token in the request object. By default, it looks for the
  108. 'format' parameter, though this may be configured. This means that, in
  109. most cases, to trigger a context switch, you can add a 'format'
  110. parameter to your request:
  111. </para>
  112. <itemizedlist>
  113. <listitem>
  114. <para>
  115. Via <acronym>URL</acronym> parameter: <filename>/news/list/format/xml</filename>
  116. (recall, the default routing schema allows for arbitrary key to value pairs
  117. following the action)
  118. </para>
  119. </listitem>
  120. <listitem>
  121. <para>
  122. Via <constant>GET</constant> parameter: <command>/news/list?format=xml</command>
  123. </para>
  124. </listitem>
  125. </itemizedlist>
  126. <para>
  127. <emphasis>ContextSwitch</emphasis> allows you to specify arbitrary contexts,
  128. including what suffix change will occur (if any), any response headers
  129. that should be sent, and arbitrary callbacks for initialization and post
  130. processing.
  131. </para>
  132. <sect4 id="zend.controller.actionhelpers.contextswitch.contexts">
  133. <title>Default Contexts Available</title>
  134. <para>
  135. By default, two contexts are available to the
  136. <emphasis>ContextSwitch</emphasis> helper: json and <acronym>XML</acronym>.
  137. </para>
  138. <itemizedlist>
  139. <listitem>
  140. <para>
  141. <emphasis><acronym>JSON</acronym></emphasis>. The <acronym>JSON</acronym>
  142. context sets the 'Content-Type' response header to
  143. '<filename>application/json</filename>', and the view script suffix to
  144. '<filename>json.phtml</filename>'.
  145. </para>
  146. <para>
  147. By default, however, no view script is required. It will
  148. simply serialize all view variables, and emit the <acronym>JSON</acronym>
  149. response immediately.
  150. </para>
  151. <para>
  152. This behaviour can be disabled by turning off the automatic
  153. <acronym>JSON</acronym> serialization:
  154. </para>
  155. <programlisting language="php"><![CDATA[
  156. $this->_helper->contextSwitch()->setAutoJsonSerialization(false);
  157. ]]></programlisting>
  158. </listitem>
  159. <listitem>
  160. <para>
  161. <emphasis><acronym>XML</acronym></emphasis>. The <acronym>XML</acronym> context
  162. sets the 'Content-Type' response header to '<filename>application/xml</filename>', and
  163. the view script suffix to '<filename>xml.phtml</filename>'. You will need to
  164. create a new view script for the context.
  165. </para>
  166. </listitem>
  167. </itemizedlist>
  168. </sect4>
  169. <sect4 id="zend.controller.actionhelpers.contextswitch.custom">
  170. <title>Creating Custom Contexts</title>
  171. <para>
  172. Sometimes, the default contexts are not enough. For instance, you may wish to return
  173. <acronym>YAML</acronym>, or serialized <acronym>PHP</acronym>, an
  174. <acronym>RSS</acronym> or <acronym>ATOM</acronym> feed, etc.
  175. <emphasis>ContextSwitch</emphasis> allows you to do so.
  176. </para>
  177. <para>
  178. The easiest way to add a new context is via the
  179. <methodname>addContext()</methodname> method. This method takes two arguments,
  180. the name of the context, and an array specification. The
  181. specification should include one or more of the following:
  182. </para>
  183. <itemizedlist>
  184. <listitem>
  185. <para>
  186. <emphasis>suffix</emphasis>: the suffix to prepend to the
  187. default view suffix as registered in the ViewRenderer.
  188. </para>
  189. </listitem>
  190. <listitem>
  191. <para>
  192. <emphasis>headers</emphasis>: an array of header to value
  193. pairs you wish sent as part of the response.
  194. </para>
  195. </listitem>
  196. <listitem>
  197. <para>
  198. <emphasis>callbacks</emphasis>: an array containing one or
  199. more of the keys 'init' or 'post', pointing to valid <acronym>PHP</acronym>
  200. callbacks that can be used for context initialization and post
  201. processing.
  202. </para>
  203. <para>
  204. Initialization callbacks occur when the context is
  205. detected by <emphasis>ContextSwitch</emphasis>. You can use it to
  206. perform arbitrary logic that should occur. As an example,
  207. the <acronym>JSON</acronym> context uses a callback to disable the ViewRenderer
  208. when the automatic <acronym>JSON</acronym> serialization is on.
  209. </para>
  210. <para>
  211. Post processing occurs during the action's
  212. <methodname>postDispatch()</methodname> routine, and can be used to perform
  213. arbitrary logic. As an example, the <acronym>JSON</acronym> context uses a
  214. callback to determine if the automatic <acronym>JSON</acronym> serialization is
  215. on; if so, it serializes the view variables to <acronym>JSON</acronym> and sends
  216. the response, but if not, it re-enables the ViewRenderer.
  217. </para>
  218. </listitem>
  219. </itemizedlist>
  220. <para>
  221. There are a variety of methods for interacting with contexts:
  222. </para>
  223. <itemizedlist>
  224. <listitem>
  225. <para>
  226. <methodname>addContext($context, array $spec)</methodname>: add a new
  227. context. Throws an exception if the context already exists.
  228. </para>
  229. </listitem>
  230. <listitem>
  231. <para>
  232. <methodname>setContext($context, array $spec)</methodname>: add a new
  233. context or overwrite an existing context. Uses the same
  234. specification as <methodname>addContext()</methodname>.
  235. </para>
  236. </listitem>
  237. <listitem>
  238. <para>
  239. <methodname>addContexts(array $contexts)</methodname>: add many contexts at
  240. once. The <varname>$contexts</varname> array should be an array of
  241. context to specification pairs. If any of the contexts already
  242. exists, it will throw an exception.
  243. </para>
  244. </listitem>
  245. <listitem>
  246. <para>
  247. <methodname>setContexts(array $contexts)</methodname>: add new contexts and
  248. overwrite existing ones. Uses the same specification as
  249. <methodname>addContexts()</methodname>.
  250. </para>
  251. </listitem>
  252. <listitem>
  253. <para>
  254. <methodname>hasContext($context)</methodname>: returns <constant>TRUE</constant> if
  255. the context exists, <constant>FALSE</constant> otherwise.
  256. </para>
  257. </listitem>
  258. <listitem>
  259. <para>
  260. <methodname>getContext($context)</methodname>: retrieve a
  261. single context by name. Returns an array following the
  262. specification used in <methodname>addContext()</methodname>.
  263. </para>
  264. </listitem>
  265. <listitem>
  266. <para>
  267. <methodname>getContexts()</methodname>: retrieve all contexts. Returns an
  268. array of context to specification pairs.
  269. </para>
  270. </listitem>
  271. <listitem>
  272. <para>
  273. <methodname>removeContext($context)</methodname>: remove a single context by
  274. name. Returns <constant>TRUE</constant> if successful,
  275. <constant>FALSE</constant> if the context was not found.
  276. </para>
  277. </listitem>
  278. <listitem>
  279. <para>
  280. <methodname>clearContexts()</methodname>: remove all contexts.
  281. </para>
  282. </listitem>
  283. </itemizedlist>
  284. </sect4>
  285. <sect4 id="zend.controller.actionhelpers.contextswitch.actions">
  286. <title>Setting Contexts Per Action</title>
  287. <para>
  288. There are two mechanisms for setting available contexts. You can
  289. either manually create arrays in your controller, or use several
  290. methods in <emphasis>ContextSwitch</emphasis> to assemble them.
  291. </para>
  292. <para>
  293. The principle method for adding action to context relations is
  294. <methodname>addActionContext()</methodname>. It expects two arguments, the
  295. action to which the context is being added, and either the name of a
  296. context or an array of contexts. As an example, consider the
  297. following controller class:
  298. </para>
  299. <programlisting language="php"><![CDATA[
  300. class FooController extends Zend_Controller_Action
  301. {
  302. public function listAction()
  303. {
  304. }
  305. public function viewAction()
  306. {
  307. }
  308. public function commentsAction()
  309. {
  310. }
  311. public function updateAction()
  312. {
  313. }
  314. }
  315. ]]></programlisting>
  316. <para>
  317. Let's say we wanted to add an <acronym>XML</acronym> context to the 'list' action, and
  318. <acronym>XML</acronym> and <acronym>JSON</acronym> contexts to the 'comments' action.
  319. We could do so in the <methodname>init()</methodname> method:
  320. </para>
  321. <programlisting language="php"><![CDATA[
  322. class FooController extends Zend_Controller_Action
  323. {
  324. public function init()
  325. {
  326. $this->_helper->contextSwitch()
  327. ->addActionContext('list', 'xml')
  328. ->addActionContext('comments', array('xml', 'json'))
  329. ->initContext();
  330. }
  331. }
  332. ]]></programlisting>
  333. <para>
  334. Alternately, you could simply define the array property
  335. <varname>$contexts</varname>:
  336. </para>
  337. <programlisting language="php"><![CDATA[
  338. class FooController extends Zend_Controller_Action
  339. {
  340. public $contexts = array(
  341. 'list' => array('xml'),
  342. 'comments' => array('xml', 'json')
  343. );
  344. public function init()
  345. {
  346. $this->_helper->contextSwitch()->initContext();
  347. }
  348. }
  349. ]]></programlisting>
  350. <para>
  351. The above is less overhead, but also prone to potential errors.
  352. </para>
  353. <para>
  354. The following methods can be used to build the context mappings:
  355. </para>
  356. <itemizedlist>
  357. <listitem>
  358. <para>
  359. <methodname>addActionContext($action, $context)</methodname>: marks one
  360. or more contexts as available to an action. If mappings
  361. already exists, simply appends to those mappings.
  362. <varname>$context</varname> may be a single context, or an array
  363. of contexts.
  364. </para>
  365. <para>
  366. A value of <constant>TRUE</constant> for the context will mark
  367. all available contexts as available for the action.
  368. </para>
  369. <para>
  370. An empty value for <varname>$context</varname> will disable all contexts for
  371. the given action.
  372. </para>
  373. </listitem>
  374. <listitem>
  375. <para>
  376. <methodname>setActionContext($action, $context)</methodname>: marks one
  377. or more contexts as available to an action. If mappings
  378. already exists, it replaces them with those specified.
  379. <varname>$context</varname> may be a single context, or an array
  380. of contexts.
  381. </para>
  382. </listitem>
  383. <listitem>
  384. <para>
  385. <methodname>addActionContexts(array $contexts)</methodname>: add several
  386. action to context pairings at once. <varname>$contexts</varname>
  387. should be an associative array of action to context pairs. It
  388. proxies to <methodname>addActionContext()</methodname>, meaning that if
  389. pairings already exist, it appends to them.
  390. </para>
  391. </listitem>
  392. <listitem>
  393. <para>
  394. <methodname>setActionContexts(array $contexts)</methodname>: acts like
  395. <methodname>addActionContexts()</methodname>, but overwrites existing
  396. action to context pairs.
  397. </para>
  398. </listitem>
  399. <listitem>
  400. <para>
  401. <methodname>hasActionContext($action, $context)</methodname>: determine
  402. if a particular action has a given context.
  403. </para>
  404. </listitem>
  405. <listitem>
  406. <para>
  407. <methodname>getActionContexts($action = null)</methodname>: returns
  408. either all contexts for a given action, or all
  409. action to context pairs.
  410. </para>
  411. </listitem>
  412. <listitem>
  413. <para>
  414. <methodname>removeActionContext($action, $context)</methodname>: remove
  415. one or more contexts from a given action.
  416. <varname>$context</varname> may be a single context or an array of
  417. contexts.
  418. </para>
  419. </listitem>
  420. <listitem>
  421. <para>
  422. <methodname>clearActionContexts($action = null)</methodname>: remove all
  423. contexts from a given action, or from all actions with
  424. contexts.
  425. </para>
  426. </listitem>
  427. </itemizedlist>
  428. </sect4>
  429. <sect4 id="zend.controller.actionhelpers.contextswitch.initcontext">
  430. <title>Initializing Context Switching</title>
  431. <para>
  432. To initialize context switching, you need to call
  433. <methodname>initContext()</methodname> in your action controller:
  434. </para>
  435. <programlisting language="php"><![CDATA[
  436. class NewsController extends Zend_Controller_Action
  437. {
  438. public function init()
  439. {
  440. $this->_helper->contextSwitch()->initContext();
  441. }
  442. }
  443. ]]></programlisting>
  444. <para>
  445. In some cases, you may want to force the context used; for instance,
  446. you may only want to allow the <acronym>XML</acronym> context if context switching is
  447. activated. You can do so by passing the context to
  448. <methodname>initContext()</methodname>:
  449. </para>
  450. <programlisting language="php"><![CDATA[
  451. $contextSwitch->initContext('xml');
  452. ]]></programlisting>
  453. </sect4>
  454. <sect4 id="zend.controller.actionhelpers.contextswitch.misc">
  455. <title>Additional Functionality</title>
  456. <para>
  457. A variety of methods can be used to alter the behaviour of the
  458. <emphasis>ContextSwitch</emphasis> helper. These include:
  459. </para>
  460. <itemizedlist>
  461. <listitem>
  462. <para>
  463. <methodname>setAutoJsonSerialization($flag)</methodname>: By default,
  464. <acronym>JSON</acronym> contexts will serialize any view variables to
  465. <acronym>JSON</acronym> notation and return this as a response. If you wish to
  466. create your own response, you should turn this off; this
  467. needs to be done prior to the call to
  468. <methodname>initContext()</methodname>.
  469. </para>
  470. <programlisting language="php"><![CDATA[
  471. $contextSwitch->setAutoJsonSerialization(false);
  472. $contextSwitch->initContext();
  473. ]]></programlisting>
  474. <para>
  475. You can retrieve the value of the flag with
  476. <methodname>getAutoJsonSerialization()</methodname>.
  477. </para>
  478. </listitem>
  479. <listitem>
  480. <para>
  481. <methodname>setSuffix($context, $suffix,
  482. $prependViewRendererSuffix)</methodname>: With this method,
  483. you can specify a different suffix to use for a given
  484. context. The third argument is used to indicate whether or
  485. not to prepend the current ViewRenderer suffix with the new
  486. suffix; this flag is enabled by default.
  487. </para>
  488. <para>
  489. Passing an empty value to the suffix will cause only the
  490. ViewRenderer suffix to be used.
  491. </para>
  492. </listitem>
  493. <listitem>
  494. <para>
  495. <methodname>addHeader($context, $header, $content)</methodname>: Add a
  496. response header for a given context. <varname>$header</varname> is
  497. the header name, and <varname>$content</varname> is the value to
  498. pass for that header.
  499. </para>
  500. <para>
  501. Each context can have multiple headers;
  502. <methodname>addHeader()</methodname> adds additional headers to the
  503. context's header stack.
  504. </para>
  505. <para>
  506. If the <varname>$header</varname> specified already exists for the
  507. context, an exception will be thrown.
  508. </para>
  509. </listitem>
  510. <listitem>
  511. <para>
  512. <methodname>setHeader($context, $header, $content)</methodname>:
  513. <methodname>setHeader()</methodname> acts just like
  514. <methodname>addHeader()</methodname>, except it allows you to overwrite
  515. existing context headers.
  516. </para>
  517. </listitem>
  518. <listitem>
  519. <para>
  520. <methodname>addHeaders($context, array $headers)</methodname>: Add
  521. multiple headers at once to a given context. Proxies to
  522. <methodname>addHeader()</methodname>, so if the header already exists,
  523. an exception will be thrown. <varname>$headers</varname> is an
  524. array of header to context pairs.
  525. </para>
  526. </listitem>
  527. <listitem>
  528. <para>
  529. <methodname>setHeaders($context, array $headers.)</methodname>: like
  530. <methodname>addHeaders()</methodname>, except it proxies to
  531. <methodname>setHeader()</methodname>, allowing you to overwrite existing
  532. headers.
  533. </para>
  534. </listitem>
  535. <listitem>
  536. <para>
  537. <methodname>getHeader($context, $header)</methodname>: retrieve the
  538. value of a header for a given context. Returns <constant>NULL</constant> if not
  539. found.
  540. </para>
  541. </listitem>
  542. <listitem>
  543. <para>
  544. <methodname>removeHeader($context, $header)</methodname>: remove a
  545. single header for a given context.
  546. </para>
  547. </listitem>
  548. <listitem>
  549. <para>
  550. <methodname>clearHeaders($context, $header)</methodname>: remove all
  551. headers for a given context.
  552. </para>
  553. </listitem>
  554. <listitem>
  555. <para>
  556. <methodname>setCallback($context, $trigger, $callback)</methodname>: set
  557. a callback at a given trigger for a given context. Triggers
  558. may be either 'init' or 'post' (indicating callback will be
  559. called at either context initialization or postDispatch).
  560. <varname>$callback</varname> should be a valid <acronym>PHP</acronym> callback.
  561. </para>
  562. </listitem>
  563. <listitem>
  564. <para>
  565. <methodname>setCallbacks($context, array $callbacks)</methodname>: set
  566. multiple callbacks for a given context. <varname>$callbacks</varname>
  567. should be trigger to callback pairs. In actuality, the most callbacks
  568. that can be registered are two, one for initialization and
  569. one for post processing.
  570. </para>
  571. </listitem>
  572. <listitem>
  573. <para>
  574. <methodname>getCallback($context, $trigger)</methodname>: retrieve a
  575. callback for a given trigger in a given context.
  576. </para>
  577. </listitem>
  578. <listitem>
  579. <para>
  580. <methodname>getCallbacks($context)</methodname>: retrieve all callbacks
  581. for a given context. Returns an array of trigger to callback
  582. pairs.
  583. </para>
  584. </listitem>
  585. <listitem>
  586. <para>
  587. <methodname>removeCallback($context, $trigger)</methodname>: remove a
  588. callback for a given trigger and context.
  589. </para>
  590. </listitem>
  591. <listitem>
  592. <para>
  593. <methodname>clearCallbacks($context)</methodname>: remove all
  594. callbacks for a given context.
  595. </para>
  596. </listitem>
  597. <listitem>
  598. <para>
  599. <methodname>setContextParam($name)</methodname>: set the request
  600. parameter to check when determining if a context switch has
  601. been requested. The value defaults to 'format', but this
  602. accessor can be used to set an alternate value.
  603. </para>
  604. <para>
  605. <methodname>getContextParam()</methodname> can be used to retrieve the
  606. current value.
  607. </para>
  608. </listitem>
  609. <listitem>
  610. <para>
  611. <methodname>setAutoDisableLayout($flag)</methodname>: By default,
  612. layouts are disabled when a context switch occurs; this is
  613. because typically layouts will only be used for returning
  614. normal responses, and have no meaning in alternate contexts.
  615. However, if you wish to use layouts (perhaps you may have a
  616. layout for the new context), you can change this behaviour
  617. by passing a <constant>FALSE</constant> value to
  618. <methodname>setAutoDisableLayout()</methodname>. You should do this
  619. <emphasis>before</emphasis> calling
  620. <methodname>initContext()</methodname>.
  621. </para>
  622. <para>
  623. To get the value of this flag, use the accessor
  624. <methodname>getAutoDisableLayout()</methodname>.
  625. </para>
  626. </listitem>
  627. <listitem>
  628. <para>
  629. <methodname>getCurrentContext()</methodname> can be used to determine
  630. what context was detected, if any. This returns <constant>NULL</constant> if no
  631. context switch occurred, or if called before
  632. <methodname>initContext()</methodname> has been invoked.
  633. </para>
  634. </listitem>
  635. </itemizedlist>
  636. </sect4>
  637. <sect4 id="zend.controller.actionhelpers.contextswitch.ajaxcontext">
  638. <title>AjaxContext Functionality</title>
  639. <para>
  640. The <emphasis>AjaxContext</emphasis> helper extends
  641. <emphasis>ContextSwitch</emphasis>, so all of the functionality listed for
  642. <emphasis>ContextSwitch</emphasis> is available to it. There are a few key
  643. differences, however.
  644. </para>
  645. <para>
  646. First, it uses a different action controller property for
  647. determining contexts, <varname>$ajaxable</varname>. This is so you can
  648. have different contexts used for <acronym>AJAX</acronym> versus normal
  649. <acronym>HTTP</acronym> requests. The various
  650. *<methodname>ActionContext()</methodname>* methods of
  651. <emphasis>AjaxContext</emphasis> will write to this property.
  652. </para>
  653. <para>
  654. Second, it will only trigger if an XmlHttpRequest has occurred, as
  655. determined by the request object's <methodname>isXmlHttpRequest()</methodname>
  656. method. Thus, if the context parameter ('format') is passed in the
  657. request, but the request was not made as an XmlHttpRequest, no
  658. context switch will trigger.
  659. </para>
  660. <para>
  661. Third, <emphasis>AjaxContext</emphasis> adds an additional context,
  662. <acronym>HTML</acronym>. In this context, it sets the suffix to
  663. '<filename>ajax.phtml</filename>' in order to differentiate the context from a normal
  664. request. No additional headers are returned.
  665. </para>
  666. <example id="zend.controller.actionhelpers.contextswitch.ajaxcontext.example">
  667. <title>Allowing Actions to Respond To Ajax Requests</title>
  668. <para>
  669. In this following example, we're allowing requests to the
  670. actions 'view', 'form', and 'process' to respond to <acronym>AJAX</acronym>
  671. requests. In the first two cases, 'view' and 'form', we'll
  672. return <acronym>HTML</acronym> snippets with which to update the page; in the
  673. latter, we'll return <acronym>JSON</acronym>.
  674. </para>
  675. <programlisting language="php"><![CDATA[
  676. class CommentController extends Zend_Controller_Action
  677. {
  678. public function init()
  679. {
  680. $ajaxContext = $this->_helper->getHelper('AjaxContext');
  681. $ajaxContext->addActionContext('view', 'html')
  682. ->addActionContext('form', 'html')
  683. ->addActionContext('process', 'json')
  684. ->initContext();
  685. }
  686. public function viewAction()
  687. {
  688. // Pull a single comment to view.
  689. // When AjaxContext detected, uses the comment/view.ajax.phtml
  690. // view script.
  691. }
  692. public function formAction()
  693. {
  694. // Render the "add new comment" form.
  695. // When AjaxContext detected, uses the comment/form.ajax.phtml
  696. // view script.
  697. }
  698. public function processAction()
  699. {
  700. // Process a new comment
  701. // Return the results as JSON; simply assign the results as
  702. // view variables, and JSON will be returned.
  703. }
  704. }
  705. ]]></programlisting>
  706. <para>
  707. On the client end, your <acronym>AJAX</acronym> library will simply request the
  708. endpoints '<filename>/comment/view</filename>',
  709. '<filename>/comment/form</filename>', and
  710. '<filename>/comment/process</filename>', and pass the 'format' parameter:
  711. '<filename>/comment/view/format/html</filename>',
  712. '<filename>/comment/form/format/html</filename>',
  713. '<filename>/comment/process/format/json</filename>'. (Or you can pass the parameter
  714. via query string: e.g., "?format=json".)
  715. </para>
  716. <para>
  717. Assuming your library passes the 'X-Requested-With:
  718. XmlHttpRequest' header, these actions will then return the
  719. appropriate response format.
  720. </para>
  721. </example>
  722. </sect4>
  723. </sect3>
  724. <!--
  725. vim:se ts=4 sw=4 et:
  726. -->