![]() |
|
The Askeet Tutorial |
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.
You are currently reading "The Askeet Tutorial" which is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.
setBody
id
![]() |
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. |
Durante el d�a ocho,
agregamos interacciones AJAX a askeet sin ning�n dolor, La aplicaci�n
es ahora bastante usable, pero podr�a usar un mont�n de peque�as
mejoras. Texto enriquecido deber�a permitirse en el body
de la pregunta, y las claves primarias no deber�an aparecer en las
URIs. Todo esto no es dif�cil de acomodar con symfony: hoy ser� una
buena ocasi�n para practicar lo que ya has aprendido, y verificar que
ya conoces como manipular todas las capas de la arquitectura MVC.
Los body de las preguntas y respuestas solo aceptan texto plano por ahora. Para permitir formateado b�sico - negrita, it�lica, hyperenlaces, im�genes, etc, . utilizaremos una librer�a externa en lugar de reinventar la rueda.
Si ya has echado un vistazo a la documentaci�n de symfony en formato de texto, probablemente sepas que somos grandes Markdown fans. Markdown es una herramienta de conversi�n de texto-a-HTML, y una sintaxis para el formateado de texto. La gran ventaja de Markdown sobre, por ejemplo, Wiki o sintaxis de foro, es que un archivo de texto markdown es muy legible:
Prueba de texto Markdown
------------------
Este es un **muy simple** ejemplo de [Markdown][1].
Lo mejor de markdown es su caracter�stica de _auto-escape_ para trozos de c�digo:
<a href="http://www.symfony-project.com">enlace a symfony</a>
>Los `<` y `>` son apropiadamente escapados como `<` y `>`,
>y no son interpretados por ninguna navegador
[1]: http://daringfireball.net/projects/markdown/ "Markdown"
El Markdown se procesa como sigue:
Prueba de texto Markdown
Este es un muy simple ejemplo de Markdown. Lo mejor de markdown es su caracter�stica de auto-escape para trozos de c�digo:
<a href="http://www.symfony-project.com">enlace a symfony</a>
Los
<
y>
son apropiadamente escapados como<
y>
, y no son interpretados por ninguna navegador
Aunque originalmente escrito en Perl, Markdown esta disponible como una librer�a PHP en PHP Markdown. �sta es la que utilizaremos. Descarga el archivo markdown.php
y ubicalo en la carpeta lib
del proyecto askeet (askeet/lib
). Eso es todo: Ahora esta disponible a todas las clases de la aplicaci�n askeet, suponiendo que la requires primero:
require_once('markdown.php');
Podr�amos llamara a la conversi�n Markdown cada vez que mostramos el
body de un mensaje, pero eso requerir�a demasiada carga en nuestros
server. En lugar convertimos el texto a HTML cuando la pregunta es
creada, y guardamos la versi�n HTML del body en la tabla Question
. Probablemente ya te hayas acostumbrando a esto, por lo que la extensi�n del modelo no ser� una sorpresa.
Primero, agrega una columna a la tabla Question
en el schema.xml
:
<column name="html_body" type="longvarchar" />
Luego, regenere el modelo y actualice la base de datos:
$ symfony propel-build-model
$ symfony propel-build-sql
$ symfony propel-insert-sql
setBody
Cuando el m�todo ->setBody()
de la clase Question
es llamado, la columna html_body
debe tambi�n ser actualizada con la conversi�n Markdown del texto del body. Abre el archivo del modelo askeet/lib/model/Question.php
, y cree:
public function setBody($v) { parent::setBody($v); require_once('markdown.php'); // strip all HTML tags $v = htmlentities($v, ENT_QUOTES, 'UTF-8'); $this->setHtmlBody(markdown($v)); }
Aplicando la funci�n htmlentities()
antes de setear el HTML protege askeet de ataques cross-site-script (XSS) pues todos los tags <script>
son escapados.
Vamos a agregar algo de formateado Markdown a algunas de las preguntas de los datos de prueba (en askeet/data/fixtures/test_data.yml
), para ser capaces de verificar que la conversi�n funciona adecuadamente:
Question:
q1:
title: What shall I do tonight with my girlfriend?
user_id: fabien
body: |
We shall meet in front of the __Dunkin'Donuts__ before dinner,
and I haven't the slightest idea of what I can do with her.
She's not interested in _programming_, _space opera movies_ nor _insects_.
She's kinda cute, so I __really__ need to find something
that will keep her to my side for another evening.
q2:
title: What can I offer to my step mother?
user_id: anonymous
body: |
My stepmother has everything a stepmother is usually offered
(watch, vacuum cleaner, earrings, [del.icio.us](http://del.icio.us) account).
Her birthday comes next week, I am broke, and I know that
if I don't offer her something *sweet*, my girlfriend
won't look at me in the eyes for another month.
Ahora puedes rellenar la base de datos:
$ php batch/load_data.php
La plantillas showSuccess.php
del modulo question
puede ser modificado levemente:
... <div class="question_body"> <?php echo $question->getHtmlBody() ?> </div> ...
La plantilla del fragmento lista (_list.php
) tambi�n muestra el body, pero en una versi�n truncada:
<div class="question_body"> <?php echo truncate_text(strip_tags($question->getHtmlBody()), 200) ?> </div>
Todo esta listo para la prueba final: mostrar las tres p�ginas que fueron modificadas y observar que el texto formateado proveniente de los datos de prueba:
http://askeet/question/list
http://askeet/recent
http://askeet/question/show/stripped_title/what-shall-i-do-tonight-with-my-girlfriend
Lo mismo par el body
para Answer
: Una columna alterna html_body
debe ser creada en el modelo, el m�todo ->setBody()
necesita ser sobreescrito, y las respuestas mostradas en question/show
deben utilizar el m�todo ->getHtmlBody()
en lugar de ->getBody()
. Como el c�digo es exactamente el mismo de arriba, no lo describimos aqu�, pero lo encontraras en el c�digo de hoy en el SVN.
id
Otra buena practica en las acciones symfony es evitar tanto como sea posible pasar claves primarias como par�metros de la petici�n. Esto es porque nuestras claves primarias son mayoritariamente auto-incrementadas, y esto da a los hackers demasiada informaci�n acerca de los registros en la base de datos. Ademas, la URI mostrada no significa nada, y esto es malo para los motores de b�squeda.
Tome la p�gina del perfil del usuario, por ejemplo. Por ahora, utiliza el id
del usuario como par�metro. Pero si nos aseguramos que el nickname
es �nico, podr�a ser utilizado como par�metro para la petici�n. Vamos a hacerlo.
Edite la acci�n user/show
:
public function executeShow() { $this->subscriber = UserPeer::retrieveByNickname($this->getRequestParameter('nickname')); $this->forward404Unless($this->subscriber); $this->interests = $this->subscriber->getInterestsJoinQuestion(); $this->answers = $this->subscriber->getAnswersJoinQuestion(); $this->questions = $this->subscriber->getQuestions(); }
Agregue el siguiente m�todo a la clase UserPeer
en el directorio askeet/lib/model
.
public static function retrieveByNickname($nickname) { $c = new Criteria(); $c->add(self::NICKNAME, $nickname); return self::doSelectOne($c); }
La p�gina que muestra un enlace al perfil del usuario debe ahora mencionar el nickname
del usuario en lugar de su id
.
En las plantillas question/showSuccess.php
, question/_list.php
, remplace:
<?php echo link_to($question->getUser(), 'user/show?id='.$question->getUserId()) ?>
por:
<?php echo link_to($question->getUser(), 'user/show?nickname='.$question->getUser()->getNickname()) ?>
El mismo tipo de modificaci�n es necesaria para las plantillas answers/_answer.php
.
Agregue nuevas reglas en la configuraci�n de ruteo para esta acci�n para que el patr�n de la url
muestra un par�metro:
user_profile:
url: /user/:nickname
param: { module: user, action: show }
Despu�s de un symfony clear-cache
, lo �ltimo por hacer es probar tus modificaciones.
Despu�s de las adicciones de hoy, muchas de las acciones escritas
asta ahora utilizan el enrutado por defecto, por lo que el nombre del
m�dulo y la acci�n son frecuentemente mostrado en la barra de direcci�n
del navegador. Ya has aprendido como corregir esto, as� que definamos
un patr�n URL para todas las acciones. Edite el archivo askeet/apps/frontend/config/routing.yml
:
# question
question:
url: /question/:stripped_title
param: { module: question, action: show }
popular_questions:
url: /index/:page
param: { module: question, action: list, page: 1 }
recent_questions:
url: /recent/:page
param: { module: question, action: recent, page: 1 }
add_question:
url: /add_question
param: { module: question, action: add }
# answer
recent_answers:
url: /recent/answers/:page
param: { module: answer, action: recent, page: 1 }
# user
login:
url: /login
param: { module: user, action: login }
logout:
url: /logout
param: { module: user, action: logout }
user_profile:
url: /user/:nickname
param: { module: user, action: show }
# default rules
homepage:
url: /
param: { module: question, action: list }
default_symfony:
url: /symfony/:action/*
param: { module: default }
default_index:
url: /:module
param: { action: index }
default:
url: /:module/:action/*
Si tu navegas en el entorno de producci�n, estas aconsejado de borrar el cache antes de probar esta modificaci�n a la configuraci�n.
Una buena pr�ctica del enrutado de symfony es utilizar nombre en el helper link_to()
en lugar de el m�dulo/acti�n
.
No solo es m�s r�pido (en motor de ruteo no tiene que paresear la
configuraci�n de enrutado para encontrar la ruta a aplicar), pero
tambi�n permite modificar la acci�n detr�s del nombre de una regla m�s
tarde. El cap�tulo de enrutado del libro de symfony explica en m�s detalles.
<?php link_to('@user_profile?id='.$user->getId()) ?> // is better than <?php link_to('user/show?id='.$user->getId()) ?>
Askeet sigue buenas pr�cticas de symfony, as� el c�digo que
descargaras al final del tutorial de este d�a contiene solo nombres de
reglas en los helpers de enlaces. Remplazando acci�n/m�dulo
por @rule
en todas las plantillas y helpers especializados no es muy divertido de
hacer, as� que el �ltimo concejo concernientes a enrutado es: Escribe
las reglas de enrutado mientras creas acciones, y utiliza los nombres
de las reglas en los helpers de enlaces desde el principio.
Los cambios de hoy fueron m�s largos de leer que de entender. Adem�s, las modificaciones descritas en el tutorial fueron repetidas para casos similares en el c�digo final. Aunque ninguna caracter�stica real fue agregada hoy, el c�digo cambi� mucho.
Si siente que no aprendi� mucho de symfony hoy, quiere decir que esta casi listo para comenzar su propio proyecto. El proceso de crear una acci�n, modificar el modelo para hacerlo servir la acci�n como es necesario, escribir plantillas simples para mostrar la acci�n y editar la configuraci�n para integrarla la nueva acci�n en la l�gica de la aplicaci�n y editar la configuraci�n para integrar la nueva acci�n son las bases del desarrollo en symfony.
Todas las buenas pr�cticas expuesta aqu� (utiliza librer�a externas
en lugar de reescrivirlas en symfony, no mostrar claves primarias en la
aplicaci�n, utilizando nombre de reglas de enrutado en lugar de m�dulo/acci�n
) mantendr�n tu aplicaci�n limpia, segura, r�pida y mantenible.
Pero la aplicaci�n askeet esta lejos de terminada! La funcionalidad m�s evidente faltante es la habilidad de agregar nuevas preguntas y de agregar un nuevo usuario. Eso es lo que desarrollaremos ma�ana.
Tienes sugerencias acerca de las caracter�sticas adicionales para el d�a 21? Asegurate de enviarlas a la lista de correos de askeet. Permanece en sinton�a!
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.