PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/jobeet/es/14.markdown

https://github.com/marydn/symfony1-docs
Markdown | 384 lines | 313 code | 71 blank | 0 comment | 0 complexity | 019b056d07ac35073a88b1da6b0587c9 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, CC-BY-SA-4.0
  1. Día 14: Feeds o Canales
  2. =======================
  3. Ayer, se comenzó a elaborar tu primer aplicación symfony. No te detengas ahora. A medida que aprendas más sobre Symfony, trata de añadir nuevas funciones a tu aplicación, alojala en algún lugar, y compartelo con la comunidad.
  4. Vamos a pasar hoy a algo completamente diferente.
  5. Si estás buscando un puesto de trabajo, es probable que desees ser informado tan pronto como un nuevo puesto de trabajo se ha publicado. Y no es muy conveniente comprobar el sitio web a cada hora. Vamos hoy a añadir feeds (o canales) de varios puestos de trabajo, para mantener a nuestros usuarios Jobeet actualizados.
  6. Formatos
  7. --------
  8. Symfony tiene soporte nativo para los formatos y tipos MIME. Esto significa que el modelo y el controlador pueden tener diferentes plantillas basadas en el formato solicitado. El formato predeterminado es HTML pero Symfony admite varios formatos de serie como ser `txt`, `js`, `css`, `json`, `xml`, `rdf`, o `atom`.
  9. El formato se puede configurar utilizando el método `setRequestFormat()` del objeto request:
  10. [php]
  11. $request->setRequestFormat('xml');
  12. Pero la mayor parte del tiempo, el formato está incluído en la URL. En este caso, Symfony lo establecerá por si la variable especial `sf_format` se utiliza en la ruta correspondiente. Para la lista de puestos de trabajo (job), la URL es:
  13. http://www.jobeet.com.localhost/frontend_dev.php/job
  14. Esta URL es equivalente a:
  15. http://www.jobeet.com.localhost/frontend_dev.php/job.html
  16. Ambas URL son equivalentes porque las rutas generadas por la clase
  17. `sfPropelRouteCollection` tienen la `sf_format` como extension. Puedes comprobarlo por mismo ejecutando la tarea `app:routes`:
  18. ![Cli](http://www.symfony-project.org/images/jobeet/1_4/15/cli.png)
  19. Feeds
  20. -----
  21. ### Feed de los Últimos Puestos de Trabajo
  22. Soportar diferentes formatos es tán fácil como la crear diferentes plantillas. Para crear un [feed Atom](http://en.wikipedia.org/wiki/Atom_(standard)) para los últimos puestos de trabajo, crea una plantilla `indexSuccess.atom.php`:
  23. [php]
  24. <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <feed xmlns="http://www.w3.org/2005/Atom">
  27. <title>Jobeet</title>
  28. <subtitle>Latest Jobs</subtitle>
  29. <link href="" rel="self"/>
  30. <link href=""/>
  31. <updated></updated>
  32. <author><name>Jobeet</name></author>
  33. <id>Unique Id</id>
  34. <entry>
  35. <title>Job title</title>
  36. <link href="" />
  37. <id>Unique id</id>
  38. <updated></updated>
  39. <summary>Job description</summary>
  40. <author><name>Company</name></author>
  41. </entry>
  42. </feed>
  43. >**SIDEBAR**
  44. >Nombres de las Plantillas
  45. >
  46. >Como `html` es el formato más utilizado para aplicaciones web, éste puede ser omitido
  47. >del nombre de la plantilla. Ambas plantillas `indexSuccess.php` y `indexSuccess.html.php`
  48. >son equivalentes y Symfony utiliza la primero que encuentre.
  49. >
  50. >¿Por qué las plantillas predeterminadas tienen el sufijo `Success`? Una acción puede devolver un valor
  51. >para indicar que plantilla se mostrará. Si la acción no dice o devuelve nada, eso
  52. >equivalente al siguiente código:
  53. >
  54. > [php]
  55. > return sfView::SUCCESS; // == 'Success'
  56. >
  57. >Si deseas cambiar el sufijo, devuelve otra cosa:
  58. >
  59. > [php]
  60. > return sfView::ERROR; // == 'Error'
  61. >
  62. > return 'Foo';
  63. >
  64. >También puedes cambiar el nombre de la plantilla utilizando el método
  65. >`setTemplate()`:
  66. > [php]
  67. > $this->setTemplate('foo');
  68. Por defecto, Symfony cambiará la respuesta `Content-Type` de acuerdo con el formato, y para todos los formatos que no sean HTML, el layout es deshabilitado. Para un Atom feed, Symfony cambiará el `Content-Type` a `application/atom+xml; charset=utf-8`.
  69. En el pie de página Jobeet, actualiza el enlace para el feed:
  70. [php]
  71. <!-- apps/frontend/templates/layout.php -->
  72. <li class="feed">
  73. <a href="<?php echo url_for('job', array('sf_format' => 'atom')) ?>">Full feed</a>
  74. </li>
  75. El URI interno es el mismo que para la lista `job` con el `sf_format` añadido como una variable.
  76. Añade una etiqueta `<link>` en la sección head del layout:
  77. [php]
  78. <!-- apps/frontend/templates/layout.php -->
  79. <link rel="alternate" type="application/atom+xml" title="Latest Jobs"
  80. href="<?php echo url_for('job', array('sf_format' => 'atom'), true) ?>" />
  81. Para el atributo `href` del enlace, se utiliza una URL absoluta gracias al segundo argumento del helper `url_for()`.
  82. Vamos a actualizar el header de la plantilla Atom:
  83. [php]
  84. <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
  85. <title>Jobeet</title>
  86. <subtitle>Latest Jobs</subtitle>
  87. <link href="<?php echo url_for('job', array('sf_format' => 'atom'), true) ?>" rel="self"/>
  88. <link href="<?php echo url_for('homepage', true) ?>"/>
  89. <propel>
  90. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', JobeetJobPeer::getLatestPost()->getCreatedAt('U')) ?></updated>
  91. </propel>
  92. <doctrine>
  93. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', Doctrine_Core::getTable('JobeetJob')->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
  94. </doctrine>
  95. <author>
  96. <name>Jobeet</name>
  97. </author>
  98. <id><?php echo sha1(url_for('job', array('sf_format' => 'atom'), true)) ?></id>
  99. <propel>
  100. Nota la utilización de `U` como argumento para `getCreatedAt()` para obtener la fecha como timestamp. Para obtener la fecha del envío, crea el método `getLatestPost()`:
  101. </propel>
  102. <doctrine>
  103. Nota la utilización de la función `strtotime()` para obtener la fecha `created_at` como timestamp. Para obtener la fecha del envío, crea el método `getLatestPost()`:
  104. </doctrine>
  105. <propel>
  106. [php]
  107. // lib/model/JobeetJobPeer.php
  108. class JobeetJobPeer extends BaseJobeetJobPeer
  109. {
  110. static public function getLatestPost()
  111. {
  112. $criteria = new Criteria();
  113. self::addActiveJobsCriteria($criteria);
  114. return JobeetJobPeer::doSelectOne($criteria);
  115. }
  116. // ...
  117. }
  118. </propel>
  119. <doctrine>
  120. [php]
  121. // lib/model/doctrine/JobeetJobTable.class.php
  122. class JobeetJobTable extends Doctrine_Table
  123. {
  124. public function getLatestPost()
  125. {
  126. $q = Doctrine_Query::create()
  127. ->from('JobeetJob j');
  128. $this->addActiveJobsQuery($q);
  129. return $q->fetchOne();
  130. }
  131. // ...
  132. }
  133. </doctrine>
  134. Los items del feed se pueden generar con el siguiente código:
  135. [php]
  136. <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
  137. <?php use_helper('Text') ?>
  138. <?php foreach ($categories as $category): ?>
  139. <?php foreach ($category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')) as $job): ?>
  140. <entry>
  141. <title>
  142. <?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)
  143. </title>
  144. <link href="<?php echo url_for('job_show_user', $job, true) ?>" />
  145. <id><?php echo sha1($job->getId()) ?></id>
  146. <propel>
  147. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getCreatedAt('U')) ?></updated>
  148. </propel>
  149. <doctrine>
  150. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getDateTimeObject('created_at')->format('U')) ?></updated>
  151. </doctrine>
  152. <summary type="xhtml">
  153. <div xmlns="http://www.w3.org/1999/xhtml">
  154. <?php if ($job->getLogo()): ?>
  155. <div>
  156. <a href="<?php echo $job->getUrl() ?>">
  157. <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>"
  158. alt="<?php echo $job->getCompany() ?> logo" />
  159. </a>
  160. </div>
  161. <?php endif ?>
  162. <div>
  163. <?php echo simple_format_text($job->getDescription()) ?>
  164. </div>
  165. <h4>How to apply?</h4>
  166. <p><?php echo $job->getHowToApply() ?></p>
  167. </div>
  168. </summary>
  169. <author>
  170. <name><?php echo $job->getCompany() ?></name>
  171. </author>
  172. </entry>
  173. <?php endforeach ?>
  174. <?php endforeach ?>
  175. El método `getHost()` del objeto request (`$sf_request`) devuelve el actual host, que viene muy bien para crear un vínculo absoluto para el logo de la empresa.
  176. ![Feed](http://www.symfony-project.org/images/jobeet/1_4/15/feed.png)
  177. >**TIP**
  178. >Cuando se crea un feed, la depuración es más fácil si utiliza herramientas de línea de comandos como
  179. >[`curl`](http://curl.haxx.se/) o
  180. >[`wget`](http://www.gnu.org/software/wget/), ya que puedes ver el contenido real
  181. >del feed.
  182. ### El Feed de los Últimos Puestos de Trabajo de una Categoría
  183. Uno de los objetivos de Jobeet es ayudar a la gente a encontrar puestos de trabajo específicos. Por lo tanto, tenemos que proporcionar un feed para cada categoría.
  184. En primer lugar, vamos a actualizar la ruta `category` para agregar el soporte para diferentes formatos:
  185. [yml]
  186. // apps/frontend/config/routing.yml
  187. category:
  188. url: /category/:slug.:sf_format
  189. class: sfPropelRoute
  190. param: { module: category, action: show, sf_format: html }
  191. options: { model: JobeetCategory, type: object }
  192. requirements:
  193. sf_format: (?:html|atom)
  194. Ahora, la ruta `category` comprenderá tanto los formatos `html` como `atom`. Actualiza los enlaces de los feeds de la categoría en las plantillas:
  195. [php]
  196. <!-- apps/frontend/modules/job/templates/indexSuccess.php -->
  197. <div class="feed">
  198. <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a>
  199. </div>
  200. [php]
  201. <!-- apps/frontend/modules/category/templates/showSuccess.php -->
  202. <div class="feed">
  203. <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a>
  204. </div>
  205. El último paso es la creación de la plantilla `showSuccess.atom.php`. Pero como este feed también lista puestos de trabajo, podemos refactorizar el código que genera los items del feed mediante la creación de un partial `_list.atom.php`. Como el formato `html`,
  206. los partial son de un formato específico:
  207. [php]
  208. <!-- apps/frontend/job/templates/_list.atom.php -->
  209. <?php use_helper('Text') ?>
  210. <?php foreach ($jobs as $job): ?>
  211. <entry>
  212. <title><?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)</title>
  213. <link href="<?php echo url_for('job_show_user', $job, true) ?>" />
  214. <id><?php echo sha1($job->getId()) ?></id>
  215. <propel>
  216. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getCreatedAt('U')) ?></updated>
  217. </propel>
  218. <doctrine>
  219. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getDateTimeObject('created_at')->format('U')) ?></updated>
  220. </doctrine>
  221. <summary type="xhtml">
  222. <div xmlns="http://www.w3.org/1999/xhtml">
  223. <?php if ($job->getLogo()): ?>
  224. <div>
  225. <a href="<?php echo $job->getUrl() ?>">
  226. <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>"
  227. alt="<?php echo $job->getCompany() ?> logo" />
  228. </a>
  229. </div>
  230. <?php endif ?>
  231. <div>
  232. <?php echo simple_format_text($job->getDescription()) ?>
  233. </div>
  234. <h4>How to apply?</h4>
  235. <p><?php echo $job->getHowToApply() ?></p>
  236. </div>
  237. </summary>
  238. <author>
  239. <name><?php echo $job->getCompany() ?></name>
  240. </author>
  241. </entry>
  242. <?php endforeach ?>
  243. Puedes utilizar el partial `_list.atom.php` para simplificar la plantilla del feed de los puestos de trabajo:
  244. [php]
  245. <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
  246. <?xml version="1.0" encoding="utf-8"?>
  247. <feed xmlns="http://www.w3.org/2005/Atom">
  248. <title>Jobeet</title>
  249. <subtitle>Latest Jobs</subtitle>
  250. <link href="<?php echo url_for('job', array('sf_format' => 'atom'), true) ?>" rel="self"/>
  251. <link href="<?php echo url_for('homepage', true) ?>"/>
  252. <propel>
  253. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', JobeetJobPeer::getLatestPost()->getCreatedAt('U')) ?></updated>
  254. </propel>
  255. <doctrine>
  256. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', Doctrine_Core::getTable('JobeetJob')->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
  257. </doctrine>
  258. <author>
  259. <name>Jobeet</name>
  260. </author>
  261. <id><?php echo sha1(url_for('job', array('sf_format' => 'atom'), true)) ?></id>
  262. <?php foreach ($categories as $category): ?>
  263. <?php include_partial('job/list', array('jobs' => $category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')))) ?>
  264. <?php endforeach ?>
  265. </feed>
  266. Finalmente, crear la plantilla `showSuccess.atom.php`:
  267. [php]
  268. <!-- apps/frontend/modules/category/templates/showSuccess.atom.php -->
  269. <?xml version="1.0" encoding="utf-8"?>
  270. <feed xmlns="http://www.w3.org/2005/Atom">
  271. <title>Jobeet (<?php echo $category ?>)</title>
  272. <subtitle>Latest Jobs</subtitle>
  273. <link href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom'), true) ?>" rel="self" />
  274. <link href="<?php echo url_for('category', array('sf_subject' => $category), true) ?>" />
  275. <propel>
  276. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $category->getLatestPost()->getCreatedAt('U')) ?></updated>
  277. </propel>
  278. <doctrine>
  279. <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $category->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
  280. </doctrine>
  281. <author>
  282. <name>Jobeet</name>
  283. </author>
  284. <id><?php echo sha1(url_for('category', array('sf_subject' => $category), true)) ?></id>
  285. <?php include_partial('job/list', array('jobs' => $pager->getResults())) ?>
  286. </feed>
  287. Para el feed principal, necesitamos la fecha del último puesto de trabajo para una categoría:
  288. [php]
  289. <propel>
  290. // lib/model/JobeetCategory.php
  291. </propel>
  292. <doctrine>
  293. // lib/model/doctrine/JobeetCategory.class.php
  294. </doctrine>
  295. class JobeetCategory extends BaseJobeetCategory
  296. {
  297. public function getLatestPost()
  298. {
  299. return $this->getActiveJobs(1)->getFirst();
  300. }
  301. // ...
  302. }
  303. ![Category Feed](http://www.symfony-project.org/images/jobeet/1_4/15/category_feed.png)
  304. Nos vemos mañana
  305. ----------------
  306. Al igual que con muchas características Symfony, el soporte de formatos nativos te permite añadir feeds a tus sitios web sin esfuerzo. Hoy, hemos mejorado la experiencia de alquien que busca empleo. Mañana, vamos a ver cómo dar una mayor exposición a los oferentes de empleo mediante el suministro de un servicio Web.
  307. Feedback
  308. --------
  309. >**Tip**
  310. >Este capítulo ha sido traducido por **Roberto Germán Puentes Díaz**.
  311. >Si encuentras algún error que deseas corregir o realizar algún comentario,
  312. >no dudes en enviarlo por correo a **puentesdiaz [arroba] gmail.com**
  313. __ORM__