The Askeet Tutorial

Be trained by symfony experts
Nov 19: Paris (1.1 - Francais)
Nov 26: Atlanta (1.1 - English)
Dec 10: Paris (1.1 - Francais)
Dec 17: Montreal (1.1 - Francais)
Jan 21: Paris (1.1 - Francais)
and more...
Askeet_logo_bar

askeet links

WARNING: The SVN source code found in the release_day tags is outdated. Please refer to the current version until each day code is updated.

About

You are currently reading "The Askeet Tutorial" which is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.

Search


powered by google

Chapter Content

Previamente en symfony

Agregar un indicador en el layout

Agregar una interacci�n AJAX para declarar inter�s

Llamador

Zona de resultados.

Acci�n del Server

Pruebas finales

Agregar un formulario de 'sign-in'

Agregar un formulario de login oculto al layout

Hacer que el formulario aparezca cuando un usuario-no-autenticado cliqueee en un enlace interested?

Loguear al usuario

Nos vemos ma�ana

You are currently browsing "The Askeet Tutorial" in Spanish for the 1.0 version. Switch to another language:
Creative Commons License This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
Translation of this work into another language is explicitly allowed.

Previamente en symfony

Despu�s de siete horas de trabajo, la aplicaci�n askeet ha avanzado bien. La p�gina de inicio muestra una lista de preguntas, el detalle de una pregunta muestra sus respuestas, los usuarios tienen una p�gina de perfil, y una lista tem�tica esta disponible para cada p�gina en la sidebar. Nuestro FAQ mejorado-por-la-comunidad esta en la direcci�n correcta (mira la lista de acciones disponibles para ayer), y el usuario aun no puede alterar su propia informaci�n por ahora.

Si la base para la manipulaci�n de datos en la web han sido por mucho tiempo los formularios, hoy t�cnicas AJAX y mejoras en la usabilidad pueden cambiar la forma en una aplicaci�n es construida. Y eso aplica a askeet, tambi�n. Este tutorial le mostrara como agregar interacciones mejoradas-por-AJAX a askeet. El objetivo es permitir al usuario registrado declarar inter�s en una pregunta.

Agregar un indicador en el layout

Mientras una petici�n as�ncrona est� pendiente, los usuario de website prove�dos de AJAX no tiene ninguna de las pistas usuales que su acci�n fue tomada en cuenta y que el resultado ser� pronto mostrado. Esta es la raz�n por la cual cada p�gina conteniendo interacciones AJAX deber�a ser capaz de mostrar un indicador de actividad.

Para este prop�sito, agregue arriba de <body> en el layout.php global:

<div id="indicator" style="display: none"></div>
 

Aunque oculto por defecto, este >div> ser� mostrado cuando una petici�n AJAX este pendiente. Esta vac�o, pero la hoja de estilo main.cc (ubicada en el directorio askeet/web/css) le da forma y contenido:

div#indicator
{
  position: absolute;
  width: 100px;
  height: 40px;
  left: 10px;
  top: 10px;
  z-index: 900;
  background: url(/images/indicator.gif) no-repeat 0 0;
}
 

indicador de actividad

Agregar una interacci�n AJAX para declarar inter�s

Una interacci�n ajax esta compuesta por tres partes: un llamador (un enlace, un bot�n o cualquier control que el usuario manipula para lanzar la acci�n), una acci�n en el servidor, y una zona en la p�gina para mostrar el resultado de la acci�n al usuario.

Llamador

Vayamos de nuevo a la muestra de la pregunta. Si recuerdas el d�a cuatro, una pregunta puede ser mostrada en la lista de preguntas y en los detalles de una pregunta.

lista de preguntas

Es por eso que el c�digo para el titulo de la pregunta y el bloque inter�s fue refactorizado en el fragmento _interested_user.php. Abre este fragmento nuevamente, y agregar un enlace para permitir a los usuario declarar sus intereses:

<?php use_helper('User') ?>
 
<div class="interested_mark" id="mark_<?php echo $question->getId() ?>">
  <?php echo $question->getInterestedUsers() ?>
</div>
 
<?php echo link_to_user_interested($sf_user, $question) ?>
 

Este enlace va a hacer m�s que simplemente redireccionar hacia otra p�gina. De hecho si ya declaro inter�s acerca de la pregunta, el/ella debe poder declararlo de nuevo. Y si el usuario no se encuentra autenticado... bueno, veremos este caso m�s tarde.

El enlace esta escrito en una funci�n helper, que necesita ser creada en askeet/apps/frontend/lib/helper/UserHelper.php:

<?php
 
use_helper('Javascript');
 
function link_to_user_interested($user, $question)
{
  if ($user->isAuthenticated())
  {
    $interested = InterestPeer::retrieveByPk($question->getId(), $user->getSubscriberId());
    if ($interested)
    {
      // already interested
      return 'interested!';
    }
    else
    {
      // didn't declare interest yet
      return link_to_remote('interested?', array(
        'url'      => 'user/interested?id='.$question->getId(),
        'update'   => array('success' => 'block_'.$question->getId()),
        'loading'  => "Element.show('indicator')",
        'complete' => "Element.hide('indicator');".visual_effect('highlight', 'mark_'.$question->getId()),
      ));
    }
  }
  else
  {
    return link_to('interested?', 'user/login');
  }
}
 
?>
 

La funci�n link_to_remote es el primer componente de una interacci�n AJAX: El llamador. Declara cual es la acci�n debe ser llamada cuando el usuario cliquea en el enlace (aqu�: user/interested) y cual zona de la p�gina necesita ser actualizada con el resultado de la acci�n (aqu�: el elemento de id block_XX). Dos manejadores de eventos (loading y complete) son agregados y asociados a las funciones javascript de prototype. La librer�a prototype ofrece herramientas javascript muy �tiles para aplicar efectos visuales en una p�gina web con un simple llamado funci�n. Su �nico defecto es la falta de documentaci�n, pero el c�digo es bastante sencillo.

Elegimos utilizar un helper en lugar de un parcial debido que esta funci�n contiene mucho m�s c�digo PHP que c�digo HTML.

No olvide agregar el id id="block_<?php echo $question->getId() ?>" al fragmento question/_list.

<div class="interested_block" id="block_<?php echo $question->getId() ?>">
  <?php include_partial('interested_user', array('question' => $question)) ?>
</div>    
 

Esto funciona solo si defini� apropiadamente el alias sf en la configuraci�n de su servidor web, como fue explicado durante el d�a uno.

Zona de resultados.

El atributo update del helper javascript link_to_remote() espec�fica la zona de resultados. En este caso, el resultado de la acci�n user/interested remplazara el contenido del elemento de id block_XX. Si se encuentra confundido, mire lo que la integraci�n del fragmento en la plantilla:

...
<div class="interested_block" id="block_<?php echo $question->getId() ?>">
  <!-- entre aqu� -->
  <?php use_helper('User') ?>
  <div class="interested_mark" id="mark_<?php echo $question->getId() ?>">
    <?php echo $question->getInterestedUsers() ?>
  </div>
  <?php echo link_to_user_interested($sf_user, $question) ?>
  <!-- y aqu� -->
</div>
...
 

La zona de resultado es la parte entre los dos comentarios. La acci�n, una vez ejecutada, remplazara este contenido.

El interese del segundo id (mark_XX) es puramente visual. El manejador del evento complete del helper link_to_remote resalta el <div> interested_mark del inter�s clicqueado... despu�s que la acci�n retorne e incremente el n�mero de inter�s.

Acci�n del Server

El llamado AJAX apunta a la acci�n user/interested. Esta acci�n debe ser crear un nuevo registro en la tabla Interest para la pregunta actual y el usuario actual. As� es como se hace en symfony:

public function executeInterested()
{
  $this->question = QuestionPeer::retrieveByPk($this->getRequestParameter('id'));
  $this->forward404Unless($this->question);
 
  $user = $this->getUser()->getSubscriber();
 
  $interest = new Interest();
  $interest->setQuestion($this->question);
  $interest->setUser($user);
  $interest->save();
}
 

Recuerde que el m�todo ->save() del objeto Interest fue modificado para incrementar el campo interested_user del User relacionado. As� el n�mero de usuarios interesados acerca de la pregunta actual ser� m�gicamente incrementada en la pantalla despu�s de la llamada a la acci�n.

�Y que deber�a mostrar la plantilla interestedSuccess.php resultante?

<?php include_partial('question/interested_user', array('question' => $question)) ?>
 

Muestra el fragmento _interested_user.php del m�dulo question. Este es el m�s grande inter�s de haber escrito este fragmento en primer lugar.

Tambi�n debemos desactivar el layout para esta plantilla (modules/user/config/view.yml):

interestedSuccess:
  has_layout: off

Pruebas finales

El desarrollo del inter�s AJAX esta terminado. Puedes probarlo ingresando un login/password existente en la p�gina de login, mostrando la lista de preguntas y luego clicqueando un enlace 'interested?'. El indicador aparece mientras la petici�n es enviada al servidor. Entonces, el numero es incrementado en remarcado cuando el servidor responde. Note que el enlace 'interested?' es ahora un texto 'interested!' sin enlace, gracias a nuestro helper link_to_user_interested:

ajax

Si desea m�s ejemplos acerca de los helpers AJAX, puedes leer el tutorial carrito de compra drag-and-drop, mira el screencast asociado o lee el capitulo relacionado del libro.

Agregar un formulario de 'sign-in'

Previamente mencionamos que s�lo usuarios registrados pueden declarar inter�s sobre un pregunta. Esto significa que si un usuario-no-autorizado cliquea en un enlace 'interested?', la p�gina de login debe ser mostrada primero.

Pero espere. �Por que un usuario cargar�a una nueva p�gina para loguearse, y perder contacto con la pregunta que el/ella ha declarado inter�s? Una mejor idea ser�a tener un formulario de login en la p�gina. Eso es lo que vamos a hacer.

Agregar un formulario de login oculto al layout

Abre el layout global (en askeet/apps/frontend/templates/layout.php), y agrega (entre el div header y el content):

<?php use_helper('Javascript') ?>
 
<div id="login" style="display: none">
  <h2>Please sign-in first</h2>
 
  <?php echo link_to_function('cancel', visual_effect('blind_up', 'login', array('duration' => 0.5))) ?>
 
  <?php echo form_tag('user/login', 'id=loginform') ?>
    nickname: <?php echo input_tag('nickname') ?><br />
    password: <?php echo input_password_tag('password') ?><br />
    <?php echo input_hidden_tag('referer', $sf_params->get('referer') ? $sf_params->get('referer') : $sf_request->getUri()) ?>
    <?php echo submit_tag('login') ?>
  </form>
</div>
 

Una vez m�s, este formulario esta escondido por defecto. La etiqueta referer contiene el par�metro referer de la petici�n si existe, o sino la actual URI.

Hacer que el formulario aparezca cuando un usuario-no-autenticado cliqueee en un enlace interested?

�Recuerdas el helper User que escribimos previamente? Ahora lidiaremos con el caso cuando el usuario no est� autenticado. Abre nuevamente el archivo askeet/lib/helper/UserHelper.php y cambie la linea:

return link_to('interested?', 'user/login');
 

con est�:

return link_to_function('interested?', visual_effect('blind_down', 'login', array('duration' => 0.5)));
 

Cuando el usuario no esta autenticado, el enlace en la la palabra 'interested?' lanza un efecto javascript de prototype (blind_down) que revela el elemento de id login - y este es el formulario que acabamos de agregar al layout.

Loguear al usuario

La acci�n user/login ya fue escrita durante el quinto d�a, y refactorizado durante el d�a seis. �Debemos modificarlo nuevamente?

public function executeLogin()
{
  if ($this->getRequest()->getMethod() != sfRequest::POST)
  {
    // display the form
    $this->getRequest()->getParameterHolder()->set('referer', $this->getRequest()->getReferer());
 
    return sfView::SUCCESS;
  }
  else
  {
    // handle the form submission
    // redirect to last page
    return $this->redirect($this->getRequestParameter('referer', '@homepage'));
  }
}
 

Despu�s de todo, no. Funciona perfectamente como esta, el manejo del referer, redireccionar� al usuario a la p�gina donde el/ella se encontraba cuando el enlace fue cliqueado.

Prueba la funcionalidad AJAX ahora. Un usuario sin registrarse ser� presentado con un formulario de login sin dejar la p�gina actual. Si el nickname y el password son reconocidos, la p�gina se refrescara y el usuario ser� capaz de cliquear en el enlace 'interested?' que intent� clicar anteriormente.

formulario de login revelado

Nota: En muchas interacciones AJAX como esta, la plantilla del servidor es simplemente un include_partial. Esto es debido a que un resultado inicial es generalmente presentado cuando la p�gina se presenta por primera vez, y porque la parte que es actualizada por la acci�n AJAX es parte de la plantilla inicial.

Nos vemos ma�ana

Lo m�s dif�cil en dise�ar interacciones AJAX es definir apropiadamente el llamador, la acci�n del server, y la zona resultante. Una vez que los conoces, symfony provee los helpers que realizan el resto. Para estar seguro de que entiendes, mira como implementamos el mismo mecanismo para declarar inter�s para la declarar inter�s para la relevancia de un respuesta. Esta vez, la acci�n AJAX llamada es user/vote, el parcial es _answer.php es separado en dos partes (creando el parcial _user_vote.php), y dos helpers link_to_user_relevancy_up() y link_to_user_relevancy_down son creado en el helper User. El m�dulo User gano una acci�n vote y una plantilla voteSuccess.php. No olvide de establecer el layout aoff` para esta plantilla tambi�n.

Askeet comienza a verse como una aplicaci�n web 2.0. Y es solo el comienzo: En unos d�as, le agregaremos algunas m�s interacciones AJAX. Ma�ana tomaremos la ocasi�n para hacer un repaso general de t�cnicas MVC en symfony, e implementar una librer�a externa.

Si encuentra un problema mientras tratas de seguir el tutorial de hoy, puedes descargar el c�digo completo etiquetado release_day_8 desde el repositorio SVN de askeet. Si no tienes ning�n problema, ven al foro askeet para responder preguntas de otros.

/askeet/1_0/es/9 »
« Calendario de symfony día siete: manipulación del modelo y las vistas

Questions & Feedback

If you find a typo or an error, please register and open a ticket.

If you need support or have a technical question, please post to the user mailing-list or to the forum.