1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 17597 -->
4 <sect3 id="zend.controller.actionhelpers.contextswitch">
5 <title>ContextSwitch con AjaxContext</title>
9 <emphasis>ContextSwitch</emphasis>
11 destinado a facilitar el regreso de respuestas de diferentes formatos de
14 <emphasis>AjaxContext</emphasis>
16 versión especializada de
17 <emphasis>ContextSwitch</emphasis>
19 facilita el regreso de respuestas a XmlHttpRequests.
22 <para>Para habilitar alguno, usted debe proporcionar indicios en su
23 controlador de qué acciones
24 pueden responder a que contextos. Si una
25 solicitud entrante indica un contexto válido para la
27 entonces el ayudante:</para>
31 <para>Deshabilita los esquemas, si están habilitados.</para>
35 <para>Establecer un sufijo de vista alternativo, requiriendo de
36 manera efectiva un script
37 de vista separado para el contexto.
42 <para>Envía las cabeceras de respuesta apropiadas para el contexto
47 <para>Opcionalmente, llama a llamadas de retorno especifícas para
48 configurar el contexto
49 y/o realizar post-procesamiento.</para>
53 <para>Como ejemplo, tomemos el siguiente controlador:</para>
55 <programlisting language="php"><![CDATA[
56 class NewsController extends Zend_Controller_Action
59 * Página final; enviar a listAction()
61 public function indexAction()
63 $this->_forward('list');
69 public function listAction()
74 * Vista del nuevo item
76 public function viewAction()
83 Digamos que queremos que
84 <methodname>listAction()</methodname>
85 también esté disponible en un formato
86 <acronym>XML</acronym>
88 de crear una acción diferente, podemos indicarle que puede devolver una
90 <acronym>XML</acronym>
94 <programlisting language="php"><![CDATA[
95 class NewsController extends Zend_Controller_Action
97 public function init()
99 $contextSwitch = $this->_helper->getHelper('contextSwitch');
100 $contextSwitch->addActionContext('list', 'xml')
108 <para>Esto es lo que hará:</para>
113 Establecer la cabecera de respuesta 'Content-Type' a
115 <filename>text/xml</filename>
122 Cambiar el sufijo de vista de '
123 <filename>xml.phtml</filename>
125 sufifo de vista alternativo, 'xml.[su sufijo]').
131 Ahora, necesitará crear un nuevo script de vista,
132 <filename>news/list.xml.phtml</filename>
133 ', que creará y mostrará a
134 <acronym>XML</acronym>
138 <para>Para determinar si una solicitud debe iniciar un cambio de contexto,
139 el ayudante comprueba
140 si hay un token en el objeto solicitud. Por
141 defecto, busca el parámetro 'format', aunque esto
142 puede ser configurado.
143 Esto significa que, en muchos casos, para provocar un cambio de
144 contexto, puede agregar un parámetro 'format' a su solicitud:</para>
150 <acronym>URL</acronym>
152 <filename>/news/list/format/xml</filename>
154 el valor por defecto del esquema de ruteo permite pares
156 clave/valor tras la acción).
163 <constant>GET</constant>
165 <command>/news/list?format=xml</command>
171 <emphasis>ContextSwitch</emphasis>
172 le permite especificar contextos
173 arbitrarios, incluso qué sufijo cambiará (si hay alguno),
175 cabecera de respuesta que deba ser enviada, y callbacks arbitrarios para
177 inicialización y posterior procesamiento.
180 <sect4 id="zend.controller.actionhelpers.contextswitch.contexts">
181 <title>Contextos Disponibles por Defecto</title>
184 Por defecto, dos contextos están a disposición del ayudante
185 <emphasis>ContextSwitch</emphasis>
187 <acronym>JSON</acronym>
189 <acronym>XML</acronym>
196 <emphasis>JSON</emphasis>
198 <acronym>JSON</acronym>
199 establece la cabecera de
200 respuesta 'Content-Type' a '
201 <filename>application/json</filename>
203 del script de vista a '
204 <filename>json.phtml</filename>
209 Sin embargo, por defecto, no es necesario un script de
211 serializará todas las variables de la
212 vista, y emitirá la respuesta
213 <acronym>JSON</acronym>
218 Este comportamiento puede ser desactivado apagando la
219 serialización automática de
220 <acronym>JSON</acronym>
224 <programlisting language="php"><![CDATA[
225 $this->_helper->contextSwitch()->setAutoJsonSerialization(false);
232 <acronym>XML</acronym>
235 <acronym>XML</acronym>
236 establece la cabecera de respuesta 'Content-Type' a
238 <filename>text/xml</filename>
239 ', y el sufijo del script de
241 <filename>xml.phtml</filename>
243 Necesitará crear un script de vista nuevo para el contexto.
249 <sect4 id="zend.controller.actionhelpers.contextswitch.custom">
250 <title>Creando Contextos Personalizados</title>
253 A veces, los contextos por defecto no son suficientes. Por
254 ejemplo, puede que desee
256 <acronym>YAML</acronym>
258 <acronym>PHP</acronym>
260 <acronym>RSS</acronym>
262 <acronym>ATOM</acronym>
264 <emphasis>ContextSwitch</emphasis>
269 La forma más fácil para añadir un nuevo contexto es a través del
271 <methodname>addContext()</methodname>
272 . Este método tiene dos
273 argumentos, el nombre del contexto, y un array de especificación.
275 especificación debería incluir uno o más de los siguientes:
281 <emphasis>suffix</emphasis>
282 : el sufijo a anteponer al
283 sufijo de la vista por defecto tal como está
291 <emphasis>headers</emphasis>
293 cabecera/valor que desea enviar como parte de la respuesta.
299 <emphasis>callbacks</emphasis>
300 : un array que contiene una
301 o más de las claves 'init' o 'post', apuntando a
303 <acronym>PHP</acronym>
304 válidos que pueden utilizarse
305 para inicializar el contexto y posterior
310 La inicialización de callbacks ocurre cuando el contexto
312 <emphasis>ContextSwitch</emphasis>
314 Usted puede usarlo para ejecutar una lógica arbitraria. Por
316 <acronym>JSON</acronym>
318 callback para desactivar a ViewRenderer cuando está activada
320 serialización auto-JSON.
324 El post procesamiento ocurre durante la rutina de la
326 <methodname>postDispatch()</methodname>
328 utilizada para ejecutar una lógica arbitraria. Como ejemplo,
331 <acronym>JSON</acronym>
332 utiliza un callback para
333 determinar si la serialización auto-JSON está activada;
335 así fuera, serializa las variables de la vista a
336 <acronym>JSON</acronym>
337 y envía la respuesta, pero si
338 no, re-habilita a ViewRenderer.
343 <para>Hay una variedad de métodos para interactuar con contextos:</para>
348 <methodname>addContext($context, array $spec)</methodname>
350 agrega un nuevo contexto. Lanza una excepción si el contexto
357 <methodname>setContext($context, array $spec)</methodname>
359 añade un nuevo contexto o sobrescribirá un contexto
360 existente. Usa la misma
362 <methodname>addContext()</methodname>
369 <methodname>addContexts(array $contexts)</methodname>
371 muchos contextos de una vez. El array
372 <varname>$contexts</varname>
374 de pares contexto/especificación. Si alguno de los contextos
375 ya existe, arrojará una excepción.
381 <methodname>setContexts(array $contexts)</methodname>
383 nuevos contextos y sobreescribe los existentes. Usa la misma
385 <methodname>addContexts()</methodname>
392 <methodname>hasContext($context)</methodname>
394 <constant>TRUE</constant>
395 si el contexto existe,
396 <constant>FALSE</constant>
403 <methodname>getContext($context)</methodname>
405 único contexto por su nombre. Devuelve un array siguiendo la
406 especificación usada en
407 <methodname>addContext()</methodname>
414 <methodname>getContexts()</methodname>
416 contextos. Devuelve un array de pares
417 contexto/especificación.
423 <methodname>removeContext($context)</methodname>
425 único contexto por su nombre. Devuelve
426 <constant>TRUE</constant>
428 <constant>FALSE</constant>
430 contexto no fue encontrado.
436 <methodname>clearContexts()</methodname>
444 <sect4 id="zend.controller.actionhelpers.contextswitch.actions">
445 <title>Estableciendo los Contextos por Acción</title>
448 Hay dos mecanismos para establecer contextos disponibles. Puede
449 crear manualmente los
450 arrays en su controlador, o utilizar varios
452 <emphasis>ContextSwitch</emphasis>
457 El método principal para añadir relaciones acción/contexto es
458 <methodname>addActionContext()</methodname>
460 argumentos, la acción a la que el contexto se añade, y el nombre de
462 contexto o un array de contextos. Como ejemplo, considere la
463 siguiente clase controlador:
466 <programlisting language="php"><![CDATA[
467 class FooController extends Zend_Controller_Action
469 public function listAction()
473 public function viewAction()
477 public function commentsAction()
481 public function updateAction()
488 Supongamos que queremos añadir un contexto
489 <acronym>XML</acronym>
490 a la acción 'list', y contextos
491 <acronym>XML</acronym>
493 <acronym>JSON</acronym>
494 a la acción 'comments'. Podríamos
496 <methodname>init()</methodname>
500 <programlisting language="php"><![CDATA[
501 class FooController extends Zend_Controller_Action
503 public function init()
505 $this->_helper->contextSwitch()
506 ->addActionContext('list', 'xml')
507 ->addActionContext('comments', array('xml', 'json'))
514 Alternativamente, puede simplemente definir la propiedad del
516 <varname>$context</varname>
520 <programlisting language="php"><![CDATA[
521 class FooController extends Zend_Controller_Action
523 public $contexts = array(
524 'list' => array('xml'),
525 'comments' => array('xml', 'json')
528 public function init()
530 $this->_helper->contextSwitch()->initContext();
535 <para>El anterior es el menos sobrecargado, pero también está expuesto
536 a posibles errores.</para>
538 <para>Los siguientes métodos pueden ser utilizados para construir los
539 mapeos del contexto:</para>
544 <methodname>addActionContext($action,
545 $context)</methodname>
546 : marca uno o más contextos como
547 disponibles para una acción. Si ya existen los
549 simplemente se añade a esos mapeos.
550 <varname>$context</varname>
552 contexto, o un array de contextos.
557 <constant>TRUE</constant>
559 contexto marcará todos los contextos como disponibles para
563 <para>Un valor vacío de $contexto desactivará todos los
564 contextos para la acción
570 <methodname>setActionContext($action,
571 $context)</methodname>
572 : marca uno o más contextos como
573 disponibles para una acción. Si el mapeo ya
575 reemplaza con los especificados.
576 <varname>$context</varname>
578 contexto, o un array de contextos.
584 <methodname>addActionContexts(array $contexts)</methodname>
586 agrega varios pares acción/contexto de una vez.
587 <varname>$contexts</varname>
589 asociativo de pares acción/contexto. Le pasa la petición a
590 <methodname>addActionContext()</methodname>
592 significa que si los emparejamientos ya existen, se añade a
599 <methodname>setActionContexts(array $contexts)</methodname>
602 <methodname>addActionContexts()</methodname>
604 pero sobreescribe pares de acción/contexto existentes.
610 <methodname>hasActionContext($action,
611 $context)</methodname>
612 : determina si una acción particular
613 tiene un contexto determinado.
619 <methodname>getActionContexts($action = null)</methodname>
621 devuelve o todos los contextos para una acción determinada,
629 <methodname>removeActionContext($action,
630 $context)</methodname>
631 : elimina uno o más contextos de
632 una acción determinada.
633 <varname>$context</varname>
634 puede ser un único contexto o un array de contextos.
640 <methodname>clearActionContexts($action =
642 : elimina todos los contextos de una
643 acción determinada, o de todas las acciones
650 <sect4 id="zend.controller.actionhelpers.contextswitch.initcontext">
651 <title>Inicializando Conmutación de Contextos (Context
655 Para inicializar la conmutación de contexto, necesita llamar a
656 <methodname>initContext()</methodname>
661 <programlisting language="php"><![CDATA[
662 class NewsController extends Zend_Controller_Action
664 public function init()
666 $this->_helper->contextSwitch()->initContext();
672 En algunos casos, puede querer forzar el contexto utilizado; por
673 ejemplo, puede que sólo
674 quiera permitir el contexto XML si la
675 conmutación de contexto está activada. Puede
678 <methodname>initContext()</methodname>
682 <programlisting language="php"><![CDATA[
683 $contextSwitch->initContext('xml');
687 <sect4 id="zend.controller.actionhelpers.contextswitch.misc">
688 <title>Funcionalidad Adicional</title>
691 Se pueden utilizar una variedad de métodos para alterar el
692 comportamiento del ayudante
693 <emphasis>ContextSwitch</emphasis>
701 <methodname>setAutoJsonSerialization($flag)</methodname>
703 Por defecto, los contextos
704 <acronym>JSON</acronym>
705 serializarán cualquier variable de vista a notación
706 <acronym>JSON</acronym>
707 y lo devolverán como una
708 respuesta. Si usted desea crear su propia respuesta,
710 deshabilitar esta opción; esto debe hacerse antes de llamar
712 <methodname>initContext()</methodname>
716 <programlisting language="php"><![CDATA[
717 $contextSwitch->setAutoJsonSerialization(false);
718 $contextSwitch->initContext();
722 Puede recuperar el valor del flag con
723 <methodname>getAutoJsonSerialization()</methodname>
730 <methodname>setSuffix($context, $suffix,
731 $prependViewRendererSuffix)</methodname>
733 método, puede especificar un sufijo diferente para
735 contexto determinado. El tercer argumento
736 es utilizado para indicar si anteponer
737 o no el actual sufijo
738 de ViewRenderer con el nuevo sufijo; este flag está
743 <para>Pasando un valor vacío para el sufijo hará que sólo el
744 sufijo ViewRenderer será
750 <methodname>addHeader($context, $header,
751 $content)</methodname>
752 : Añadir una cabecera de respuesta
753 para un determinado contexto.
754 <varname>$header</varname>
757 <varname>$content</varname>
759 pasar por esa cabecera.
763 Cada contexto pueden tener múltiples cabeceras;
764 <methodname>addHeader()</methodname>
766 adicionales al stack de cabecera del contexto.
771 <varname>$header</varname>
773 existe para el contexto, arrojará una excepción.
779 <methodname>setHeader($context, $header,
780 $content)</methodname>
782 <methodname>setHeader()</methodname>
784 <methodname>addHeader()</methodname>
786 permite sobreescribir cabeceras del contexto actual.
792 <methodname>addHeaders($context, array
793 $headers)</methodname>
794 : Añade varias cabeceras de una
795 vez a un determinado contexto. Delega a
796 <methodname>addHeader()</methodname>
798 cabecera ya existe, arrojará una excepción.
799 <varname>$headers</varname>
807 <methodname>setHeaders($context, array
808 $headers.)</methodname>
810 <methodname>addHeaders()</methodname>
813 <methodname>setHeader()</methodname>
815 permitiéndole sobreescribir las cabeceras existentes.
821 <methodname>getHeader($context, $header)</methodname>
823 recuperar el valor de una cabecera para un determinado
824 contexto. Retorna null si
831 <methodname>removeHeader($context, $header)</methodname>
833 eliminar una única cabecera para un determinado contexto.
839 <methodname>clearHeaders($context, $header)</methodname>
841 eliminar todas las cabeceras para un determinado contexto.
847 <methodname>setCallback($context, $trigger,
848 $callback)</methodname>
849 : establecer un callback en un
850 determinado disparador para poner en marcha un
852 contexto. Los disparadores pueden ser 'init' o 'post'
854 se llamará a un callback para cada contexto
855 de inicialización o postDispatch).
856 <varname>$callback</varname>
859 <acronym>PHP</acronym>
866 <methodname>setCallbacks($context, array
867 $callbacks)</methodname>
868 : establece varios callbacks
869 para un determinado contexto.
870 <varname>$callbacks</varname>
872 diparadores/callbacks. En realidad, la mayor cantidad de
873 callbacks que pueden ser registrados son dos, uno para la
874 inicialización y otro
875 para el procesamiento posterior.
881 <methodname>getCallback($context, $trigger)</methodname>
883 recuperar un callback para un determinado disparador en un
890 <methodname>getCallbacks($context)</methodname>
892 todos los callbacks para un determinado contexto. Devuelve
894 pares disparor/callback.
900 <methodname>removeCallback($context, $trigger)</methodname>
902 elimina un callback para un determinado disparador y
909 <methodname>clearCallbacks($context)</methodname>
911 todos los callbacks para un determinado contexto.
917 <methodname>setContextParam($name)</methodname>
919 el parámetro de petición para comprobar si un conmutador de
921 ha sido solicitado. El valor por defecto es
922 'format', pero este accededor puede
924 establecer un valor alternativo.
928 <methodname>getContextParam()</methodname>
930 utilizado para recuperar el valor actual.
936 <methodname>setAutoDisableLayout($flag)</methodname>
938 defecto, los esquemas están deshabilitados cuando sucede una
940 contexto; esto es porque normalmente los
941 esquemas sólo serán utilizados para
943 normales, y no tienen sentido en otros contextos. Sin
944 embargo, si desea usar esquemas (tal vez puede tener un
946 contexto), puede cambiar este
947 comportamiento pasando un valor falso a
948 <methodname>setAutoDisableLayout()</methodname>
951 <emphasis>antes</emphasis>
953 <methodname>initContext()</methodname>
958 Para conseguir el valor de este flag, utilice el
960 <methodname>getAutoDisableLayout()</methodname>
967 <methodname>getCurrentContext()</methodname>
969 utilizado para determinar qué contexto fue detectado, si hay
971 Este retorna null si no hubo conmutación de
973 <methodname>initContext()</methodname>
975 llamado antes de ser invocado.
981 <sect4 id="zend.controller.actionhelpers.contextswitch.ajaxcontext">
982 <title>Funcionalidad de AjaxContext</title>
986 <emphasis>AjaxContext</emphasis>
988 <emphasis>ContextSwitch</emphasis>
990 funcionalidad listada para
991 <emphasis>ContextSwitch</emphasis>
992 está disponible. Hay algunas diferencias fundamentales, sin embargo.
996 En primer lugar, el controlador de acción utiliza una propiedad
997 diferente para determinar
999 <varname>$ajaxable</varname>
1000 . Esto es, que puede tener
1001 diferentes contextos utilizados para
1002 <acronym>AJAX</acronym>
1005 <acronym>HTTP</acronym>
1006 . Los diversos métodos
1007 <methodname>*ActionContext*()</methodname>
1009 <emphasis>AjaxContext</emphasis>
1010 le escribirán a esta
1015 En segundo lugar, sólo se disparará si se produjo un
1016 XmlHttpRequest, según lo determinado
1017 por la solicitud del método del
1019 <methodname>isXmlHttpRequest()</methodname>
1021 el parámetro de contexto ('format') en la solicitud, pero la
1023 no fue hecha como un XmlHttpRequest, no se disparará
1024 ninguna conmutación de contexto.
1029 <emphasis>AjaxContext</emphasis>
1032 <acronym>HTML</acronym>
1033 . En este contexto, se establece el sufijo a
1035 <filename>ajax.phtml</filename>
1036 ' para diferenciar el contexto de una solicitud normal.
1037 No se devuelven cabeceras
1041 <example id="zend.controller.actionhelpers.contextswitch.ajaxcontext.example">
1042 <title>Permitiendo a las Acciones Responder a Requerimientos
1046 En el siguiente ejemplo, estamos permitiendo requerimientos a
1047 las acciones 'view',
1048 'form', y 'process' para responder a
1050 <acronym>AJAX</acronym>
1051 . En los dos primeros casos,
1052 'view' y 'form', devolveremos fragmentos (snippets) de
1053 <acronym>HTML</acronym>
1055 los cuales actualizaremos la página; y en el último,
1057 <acronym>JSON</acronym>
1061 <programlisting language="php"><![CDATA[
1062 class CommentController extends Zend_Controller_Action
1064 public function init()
1066 $ajaxContext = $this->_helper->getHelper('AjaxContext');
1067 $ajaxContext->addActionContext('view', 'html')
1068 ->addActionContext('form', 'html')
1069 ->addActionContext('process', 'json')
1073 public function viewAction()
1075 // Tirar para ver un único comentario.
1076 // Cuando se detecta AjaxContext, utiliza el script de vista
1077 // comment/view.ajax.phtml.
1080 public function formAction()
1082 // Mostrar el form "add new comment".
1083 // Cuando se detecta AjaxContext, utiliza el script de vista
1084 // comment/form.ajax.phtml.
1087 public function processAction()
1089 // Procesar un nuevo comentario
1090 // Devolver los resultados como JSON; simplemente asignar los
1091 // resultados como variables de la vista, y se devolverán como JSON.
1095 ]]></programlisting>
1098 En el lado del cliente, su biblioteca
1099 <acronym>AJAX</acronym>
1100 simplemente pedirá los parámetros finales '
1101 <filename>/comment/view</filename>
1104 <filename>/comment/form</filename>
1106 <filename>/comment/process</filename>
1107 ', y pasar el parámetro
1109 <filename>/comment/view/format/html</filename>
1112 <filename>/comment/form/format/html</filename>
1114 <filename>/comment/process/format/json</filename>
1116 puede pasar el parámetro via string de consulta: ejemplo
1120 <para>Asumiendo que su biblioteca pasa la cabecera
1121 'X-Requested-With:XmlHttpRequest'
1122 entonces estas acciones
1123 devolverán la respuesta en el formato apropiado.</para>