PageRenderTime 34ms CodeModel.GetById 8ms app.highlight 22ms RepoModel.GetById 1ms 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
  1Día 14: Feeds o Canales
  2=======================
  3
  4Ayer, 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.
  5
  6Vamos a pasar hoy a algo completamente diferente.
  7
  8Si 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.
  9
 10Formatos
 11--------
 12
 13Symfony 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`.
 14
 15El formato se puede configurar utilizando el método `setRequestFormat()` del objeto request:
 16
 17    [php]
 18    $request->setRequestFormat('xml');
 19
 20Pero la mayor parte del tiempo, el formato está incluído en la URL. En este caso, Symfony lo establecerá por tí si la variable especial `sf_format` se utiliza en la ruta correspondiente. Para la lista de puestos de trabajo (job), la URL es:
 21
 22    http://www.jobeet.com.localhost/frontend_dev.php/job
 23
 24Esta URL es equivalente a:
 25
 26    http://www.jobeet.com.localhost/frontend_dev.php/job.html
 27
 28Ambas URL son equivalentes porque las rutas generadas por la clase 
 29`sfPropelRouteCollection` tienen la `sf_format` como extension. Puedes comprobarlo por tí mismo ejecutando la tarea `app:routes`:
 30
 31![Cli](http://www.symfony-project.org/images/jobeet/1_4/15/cli.png)
 32
 33Feeds
 34-----
 35
 36### Feed de los Últimos Puestos de Trabajo
 37
 38Soportar 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`:
 39
 40    [php]
 41    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
 42    <?xml version="1.0" encoding="utf-8"?>
 43    <feed xmlns="http://www.w3.org/2005/Atom">
 44      <title>Jobeet</title>
 45      <subtitle>Latest Jobs</subtitle>
 46      <link href="" rel="self"/>
 47      <link href=""/>
 48      <updated></updated>
 49      <author><name>Jobeet</name></author>
 50      <id>Unique Id</id>
 51
 52      <entry>
 53        <title>Job title</title>
 54        <link href="" />
 55        <id>Unique id</id>
 56        <updated></updated>
 57        <summary>Job description</summary>
 58        <author><name>Company</name></author>
 59      </entry>
 60    </feed>
 61
 62>**SIDEBAR**
 63>Nombres de las Plantillas
 64>
 65>Como `html` es el formato más utilizado para aplicaciones web, éste puede ser omitido
 66>del nombre de la plantilla. Ambas plantillas `indexSuccess.php` y `indexSuccess.html.php`
 67>son equivalentes y Symfony utiliza la primero que encuentre.
 68>
 69>¿Por qué las plantillas predeterminadas tienen el sufijo `Success`? Una acción puede devolver un valor
 70>para indicar que plantilla se mostrará. Si la acción no dice o devuelve nada, eso
 71>equivalente al siguiente código:
 72>
 73>     [php]
 74>     return sfView::SUCCESS; // == 'Success'
 75>
 76>Si deseas cambiar el sufijo, devuelve otra cosa:
 77>
 78>     [php]
 79>     return sfView::ERROR; // == 'Error'
 80>
 81>     return 'Foo';
 82>
 83>También puedes cambiar el nombre de la plantilla utilizando el método
 84>`setTemplate()`:
 85
 86>     [php]
 87>     $this->setTemplate('foo');
 88
 89Por 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`.
 90
 91En el pie de página Jobeet, actualiza el enlace para el feed:
 92
 93    [php]
 94    <!-- apps/frontend/templates/layout.php -->
 95    <li class="feed">
 96      <a href="<?php echo url_for('job', array('sf_format' => 'atom')) ?>">Full feed</a>
 97    </li>
 98
 99El URI interno es el mismo que para la lista `job` con el `sf_format` añadido como una variable.
100
101Añade una etiqueta `<link>` en la sección head del layout:
102
103    [php]
104    <!-- apps/frontend/templates/layout.php -->
105    <link rel="alternate" type="application/atom+xml" title="Latest Jobs"
106      href="<?php echo url_for('job', array('sf_format' => 'atom'), true) ?>" />
107
108Para el atributo `href` del enlace, se utiliza una URL absoluta gracias al segundo argumento del helper `url_for()`.
109
110Vamos a actualizar el header de la plantilla Atom:
111
112    [php]
113    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
114    <title>Jobeet</title>
115    <subtitle>Latest Jobs</subtitle>
116    <link href="<?php echo url_for('job', array('sf_format' => 'atom'), true) ?>" rel="self"/>
117    <link href="<?php echo url_for('homepage', true) ?>"/>
118<propel>
119    <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', JobeetJobPeer::getLatestPost()->getCreatedAt('U')) ?></updated>
120</propel>
121<doctrine>
122    <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', Doctrine_Core::getTable('JobeetJob')->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
123</doctrine>
124    <author>
125      <name>Jobeet</name>
126    </author>
127    <id><?php echo sha1(url_for('job', array('sf_format' => 'atom'), true)) ?></id>
128
129<propel>
130Nota 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()`:
131</propel>
132<doctrine>
133Nota 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()`:
134</doctrine>
135
136<propel>
137    [php]
138    // lib/model/JobeetJobPeer.php
139    class JobeetJobPeer extends BaseJobeetJobPeer
140    {
141      static public function getLatestPost()
142      {
143        $criteria = new Criteria();
144        self::addActiveJobsCriteria($criteria);
145
146        return JobeetJobPeer::doSelectOne($criteria);
147      }
148
149      // ...
150    }
151</propel>
152<doctrine>
153    [php]
154    // lib/model/doctrine/JobeetJobTable.class.php
155    class JobeetJobTable extends Doctrine_Table
156    {
157      public function getLatestPost()
158      {
159        $q = Doctrine_Query::create()
160          ->from('JobeetJob j');
161        $this->addActiveJobsQuery($q);
162
163        return $q->fetchOne();
164      }
165
166      // ...
167    }
168</doctrine>
169
170Los items del feed se pueden generar con el siguiente código:
171
172    [php]
173    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
174    <?php use_helper('Text') ?>
175    <?php foreach ($categories as $category): ?>
176      <?php foreach ($category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')) as $job): ?>
177        <entry>
178          <title>
179            <?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)
180          </title>
181          <link href="<?php echo url_for('job_show_user', $job, true) ?>" />
182          <id><?php echo sha1($job->getId()) ?></id>
183<propel>
184          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getCreatedAt('U')) ?></updated>
185</propel>
186<doctrine>
187          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getDateTimeObject('created_at')->format('U')) ?></updated>
188</doctrine>
189          <summary type="xhtml">
190           <div xmlns="http://www.w3.org/1999/xhtml">
191             <?php if ($job->getLogo()): ?>
192               <div>
193                 <a href="<?php echo $job->getUrl() ?>">
194                   <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>"
195                     alt="<?php echo $job->getCompany() ?> logo" />
196                 </a>
197               </div>
198             <?php endif ?>
199
200             <div>
201               <?php echo simple_format_text($job->getDescription()) ?>
202             </div>
203
204             <h4>How to apply?</h4>
205
206             <p><?php echo $job->getHowToApply() ?></p>
207           </div>
208          </summary>
209          <author>
210            <name><?php echo $job->getCompany() ?></name>
211          </author>
212        </entry>
213      <?php endforeach ?>
214    <?php endforeach ?>
215
216El 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.
217
218![Feed](http://www.symfony-project.org/images/jobeet/1_4/15/feed.png)
219
220>**TIP**
221>Cuando se crea un feed, la depuración es más fácil si utiliza herramientas de línea de comandos como
222>[`curl`](http://curl.haxx.se/) o
223>[`wget`](http://www.gnu.org/software/wget/), ya que puedes ver el contenido real 
224>del feed.
225
226### El Feed de los Últimos Puestos de Trabajo de una Categoría
227
228Uno 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.
229
230En primer lugar, vamos a actualizar la ruta `category` para agregar el soporte para diferentes formatos:
231
232    [yml]
233    // apps/frontend/config/routing.yml
234    category:
235      url:     /category/:slug.:sf_format
236      class:   sfPropelRoute
237      param:   { module: category, action: show, sf_format: html }
238      options: { model: JobeetCategory, type: object }
239      requirements:
240        sf_format: (?:html|atom)
241
242Ahora, la ruta `category` comprenderá tanto los formatos `html` como `atom`. Actualiza los enlaces de los feeds de la categoría en las plantillas:
243
244    [php]
245    <!-- apps/frontend/modules/job/templates/indexSuccess.php -->
246    <div class="feed">
247      <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a>
248    </div>
249
250    [php]
251    <!-- apps/frontend/modules/category/templates/showSuccess.php -->
252    <div class="feed">
253      <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a>
254    </div>
255
256El ú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`,
257los partial son de un formato específico:
258
259    [php]
260    <!-- apps/frontend/job/templates/_list.atom.php -->
261    <?php use_helper('Text') ?>
262
263    <?php foreach ($jobs as $job): ?>
264      <entry>
265        <title><?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)</title>
266        <link href="<?php echo url_for('job_show_user', $job, true) ?>" />
267        <id><?php echo sha1($job->getId()) ?></id>
268<propel>
269          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getCreatedAt('U')) ?></updated>
270</propel>
271<doctrine>
272          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getDateTimeObject('created_at')->format('U')) ?></updated>
273</doctrine>
274        <summary type="xhtml">
275         <div xmlns="http://www.w3.org/1999/xhtml">
276           <?php if ($job->getLogo()): ?>
277             <div>
278               <a href="<?php echo $job->getUrl() ?>">
279                 <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>"
280                   alt="<?php echo $job->getCompany() ?> logo" />
281               </a>
282             </div>
283           <?php endif ?>
284
285           <div>
286             <?php echo simple_format_text($job->getDescription()) ?>
287           </div>
288
289           <h4>How to apply?</h4>
290
291           <p><?php echo $job->getHowToApply() ?></p>
292         </div>
293        </summary>
294        <author>
295          <name><?php echo $job->getCompany() ?></name>
296        </author>
297      </entry>
298    <?php endforeach ?>
299    
300Puedes utilizar el partial `_list.atom.php` para simplificar la plantilla del feed de los puestos de trabajo:
301
302    [php]
303    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
304    <?xml version="1.0" encoding="utf-8"?>
305    <feed xmlns="http://www.w3.org/2005/Atom">
306      <title>Jobeet</title>
307      <subtitle>Latest Jobs</subtitle>
308      <link href="<?php echo url_for('job', array('sf_format' => 'atom'), true) ?>" rel="self"/>
309      <link href="<?php echo url_for('homepage', true) ?>"/>
310<propel>
311      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', JobeetJobPeer::getLatestPost()->getCreatedAt('U')) ?></updated>
312</propel>
313<doctrine>
314      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', Doctrine_Core::getTable('JobeetJob')->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
315</doctrine>
316      <author>
317        <name>Jobeet</name>
318      </author>
319      <id><?php echo sha1(url_for('job', array('sf_format' => 'atom'), true)) ?></id>
320
321    <?php foreach ($categories as $category): ?>
322      <?php include_partial('job/list', array('jobs' => $category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')))) ?>
323    <?php endforeach ?>
324    </feed>
325
326Finalmente, crear la plantilla `showSuccess.atom.php`:
327
328    [php]
329    <!-- apps/frontend/modules/category/templates/showSuccess.atom.php -->
330    <?xml version="1.0" encoding="utf-8"?>
331    <feed xmlns="http://www.w3.org/2005/Atom">
332      <title>Jobeet (<?php echo $category ?>)</title>
333      <subtitle>Latest Jobs</subtitle>
334      <link href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom'), true) ?>" rel="self" />
335      <link href="<?php echo url_for('category', array('sf_subject' => $category), true) ?>" />
336<propel>
337      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $category->getLatestPost()->getCreatedAt('U')) ?></updated>
338</propel>
339<doctrine>
340      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $category->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
341</doctrine>
342      <author>
343        <name>Jobeet</name>
344      </author>
345      <id><?php echo sha1(url_for('category', array('sf_subject' => $category), true)) ?></id>
346
347      <?php include_partial('job/list', array('jobs' => $pager->getResults())) ?>
348    </feed>
349
350Para el feed principal, necesitamos la fecha del último puesto de trabajo para una categoría:
351
352    [php]
353<propel>
354    // lib/model/JobeetCategory.php
355</propel>
356<doctrine>
357    // lib/model/doctrine/JobeetCategory.class.php
358</doctrine>
359    class JobeetCategory extends BaseJobeetCategory
360    {
361      public function getLatestPost()
362      {
363        return $this->getActiveJobs(1)->getFirst();
364      }
365
366      // ...
367    }
368
369![Category Feed](http://www.symfony-project.org/images/jobeet/1_4/15/category_feed.png)
370
371Nos vemos mañana
372----------------
373
374Al 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.
375
376Feedback
377--------
378
379>**Tip**
380>Este capítulo ha sido traducido por **Roberto Germán Puentes Díaz**. 
381>Si encuentras algún error que deseas corregir o realizar algún comentario,
382>no dudes en enviarlo por correo a **puentesdiaz [arroba] gmail.com**
383
384__ORM__