gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Vuelve a la página "show" para una cuestión. El logo de arriba es un link... que no va a ninguna parte aún. Este debería llevarnos a la página de inicio.
Como forma parte del layout, el link vive en base.html.twig
. Aquí está: navbar-brand
con href="#"
.
... line 1 | |
<html> | |
... lines 3 - 12 | |
<body> | |
<nav class="navbar navbar-light bg-light" style="height: 100px;"> | |
<a class="navbar-brand" href="#"> | |
... lines 16 - 17 | |
</a> | |
... line 19 | |
</nav> | |
... lines 21 - 26 | |
</body> | |
</html> |
Para hacer que esto nos lleve a la página de inicio, podemos simplemente cambiarlo a /
, ¿Cierto? Podrías hacerlo, pero en Symfony, una mejor forma es pedirle a Symfony que genere una URL hacia esta ruta. De esta forma, si decidimos cambiar esta URL en el futuro, todos nuestros links se actualizarán automáticamente.
Para ver cómo hacer esto, ve a tu terminal y corre:
php bin/console debug:router
Esto muestra un listado de cada ruta del sistema... ¡Y, hey! Desde la última vez que lo corrimos, hay un montón de rutas nuevas. Estas alimentan a la barra de herramientas debug y el profiler y son agregadas automáticamente por el WebProfilerBundle cuando estamos en modo dev
.
De todas formas, lo que realmente quiero ver es la columna "Name". Toda ruta tiene un nombre interno, incluyendo las dos rutas que hicimos. Aparentemente sus nombres son app_question_homepage
y app_question_show
. Pero... eh... ¿De dónde vinieron? ¡No recuerdo haber escrito ninguno de éstos!
Entonces... A cada ruta debe serle dada un nombre interno. Pero cuando usas rutas en anotación... te deja hacer trampa: elige un nombre por ti basado en la clase y método del controlador... ¡Lo cual es asombroso!
Pero... tan pronto como necesitas generar la URL de una ruta, yo recomiendo darle un nombre explícito, en lugar de depender de este nombre autogenerado, el cual podría cambiar de repente si le cambias el nombre al método. Para darle un nombre a una ruta, agrega name=""
y... Que tal: app_homepage
.
... lines 1 - 8 | |
class QuestionController extends AbstractController | |
{ | |
/** | |
* @Route("/", name="app_homepage") | |
*/ | |
public function homepage() | |
{ | |
... line 16 | |
} | |
... lines 18 - 34 | |
} |
Me gusta mantener los nombres de mis rutas cortos, pero app_
lo hace lo suficientemente largo como para poder realizar una búsqueda a partir de esta cadena si alguna vez lo necesito.
Ahora, si corremos debug:router
nuevamente:
php bin/console debug:router
¡Bien! Tomamos el control del nombre de nuestra ruta. Copia el nombre app_homepage
y luego vuelve a base.html.twig
. El objetivo es simple, queremos decir:
¡Hey symfony! ¿Puedes por favor decirme la URL para la ruta
app_homepage
?
Para hacer esto en Twig, usa {{ path() }}
y pásale el nombre de la ruta.
... line 1 | |
<html> | |
... lines 3 - 12 | |
<body> | |
<nav class="navbar navbar-light bg-light" style="height: 100px;"> | |
<a class="navbar-brand" href="{{ path('app_homepage') }}"> | |
... lines 16 - 17 | |
</a> | |
... line 19 | |
</nav> | |
... lines 21 - 26 | |
</body> | |
</html> |
¡Eso es todo! Cuando volvemos y refrescamos... Ahora esto va hacia la página principal.
En la página principal, tenemos dos preguntas escritas a mano... y cada una tiene dos links que actualmente no van a ninguna parte. ¡Arreglémoslos!
Paso uno: ahora que queremos generar una URL de esta ruta, encuentra la ruta y agrega name="app_question_show"
.
... lines 1 - 8 | |
class QuestionController extends AbstractController | |
{ | |
... lines 11 - 18 | |
/** | |
* @Route("/questions/{slug}", name="app_question_show") | |
*/ | |
public function show($slug) | |
{ | |
... lines 24 - 33 | |
} | |
} |
Copia esto y abre el template: templates/question/homepage.html.twig
. Veamos... Justo debajo de la parte de votar, aquí está el primer link a una pregunta que dice "Reversing a spell". Quita el signo numeral, agrega {{ path() }}
y pega app_question_show
.
Pero... no podemos detenernos aquí. ¡Si probamos la página ahora, un error glorioso!
Algunos parámetros obligatorios están faltando - "slug"
¡Eso tiene sentido! ¡No podemos simplemente decir "genera la URL hacia app_question_show
" porque esa ruta tiene un comodín! Symfony necesita saber qué valor debería usar para {slug}
. ¿Cómo le decimos? Agrega un segundo parámetro a path()
con {}
. El {}
es un array asociativo de Twig... nuevamente, tal como en JavaScript. Pásale slug
igual a... Veamos... Esta es una pregunta escrita a mano por el momento, así que escribe reversing-a-spell
.
... lines 1 - 2 | |
{% block body %} | |
... lines 4 - 9 | |
<div class="container"> | |
... lines 11 - 15 | |
<div class="row"> | |
<div class="col-12"> | |
<div style="box-shadow: 2px 3px 9px 4px rgba(0,0,0,0.04);"> | |
<div class="q-container p-4"> | |
<div class="row"> | |
... lines 21 - 27 | |
<div class="col"> | |
<a class="q-title" href="{{ path('app_question_show', { slug: 'reversing-a-spell' }) }}"><h2>Reversing a Spell</h2></a> | |
... lines 30 - 34 | |
</div> | |
</div> | |
</div> | |
<a class="answer-link" href="{{ path('app_question_show', { slug: 'reversing-a-spell' }) }}" style="color: #fff;"> | |
... lines 39 - 41 | |
</a> | |
</div> | |
</div> | |
... lines 45 - 71 | |
</div> | |
</div> | |
{% endblock %} | |
... lines 75 - 76 |
Cópialo todo, porque hay un link más aquí abajo para la misma pregunta. Para la segunda pregunta... Pégalo nuevamente, pero cámbialo a pausing-a-spell
para igualar el nombre. Copiaré eso... Encuentra la última ocurrencia... Y pégalo.
... lines 1 - 2 | |
{% block body %} | |
... lines 4 - 9 | |
<div class="container"> | |
... lines 11 - 15 | |
<div class="row"> | |
... lines 17 - 45 | |
<div class="col-12 mt-3"> | |
<div class="q-container p-4"> | |
<div class="row"> | |
... lines 49 - 55 | |
<div class="col"> | |
<a class="q-title" href="{{ path('app_question_show', { slug: 'pausing-a-spell' }) }}"><h2>Pausing a Spell</h2></a> | |
... lines 58 - 62 | |
</div> | |
</div> | |
</div> | |
<a class="answer-link" href="{{ path('app_question_show', { slug: 'pausing-a-spell' }) }}" style="color: #fff;"> | |
... lines 67 - 69 | |
</a> | |
</div> | |
</div> | |
</div> | |
{% endblock %} | |
... lines 75 - 76 |
Más adelante, cuando implementemos una base de datos, vamos a mejorar esto y evitaremos repetirnos tantas veces. ¡Pero! Si volvemos, refrescamos... ¡Y hacemos click en el link, funciona! Ambas páginas van hacia la misma ruta, pero con un valor diferente para el slug.
A continuación, llevemos nuestro sitio al siguiente nivel, al crear una interface API JSON que consumiremos con JavaScript.
Hey Joaquim P.!
Ah, actually I think it IS correct (but I appreciate you making sure anyway!). The tricky thing here is that, in this tutorial, we're using route annotations (the stuff that starts with an @ symbol). Lately, you're probably more accustomed to seeing route *attributes (the stuff that is surrounded by #[]). For annotations, the name="app_user_profile"
is correct. For attributes, the name:
would be correct. But, anyways, I'm happy to say goodbye to annotations in favor or attributes ;).
Cheers!
Thank you Ryan!
Oh yes, of course you're right! My bad. In fact, I was confusing attributes and annotations :)
Till now I love the course, thank you so much. But man, the last sentence, i'm scared. Let's continue.
Hey TanguyD,
Haha, I hope it won't scare you anymore after you finish this course ;) Thanks for your feedback!
Cheers!
// composer.json
{
"require": {
"php": "^7.3.0 || ^8.0.0",
"ext-ctype": "*",
"ext-iconv": "*",
"easycorp/easy-log-handler": "^1.0.7", // v1.0.9
"sensio/framework-extra-bundle": "^6.0", // v6.2.1
"symfony/asset": "5.0.*", // v5.0.11
"symfony/console": "5.0.*", // v5.0.11
"symfony/debug-bundle": "5.0.*", // v5.0.11
"symfony/dotenv": "5.0.*", // v5.0.11
"symfony/flex": "^1.3.1", // v1.17.5
"symfony/framework-bundle": "5.0.*", // v5.0.11
"symfony/monolog-bundle": "^3.0", // v3.5.0
"symfony/profiler-pack": "*", // v1.0.5
"symfony/routing": "5.1.*", // v5.1.11
"symfony/twig-pack": "^1.0", // v1.0.1
"symfony/var-dumper": "5.0.*", // v5.0.11
"symfony/webpack-encore-bundle": "^1.7", // v1.8.0
"symfony/yaml": "5.0.*" // v5.0.11
},
"require-dev": {
"symfony/profiler-pack": "^1.0" // v1.0.5
}
}
Hi! Great Tutorials! Congrats!
Just a notice: There is a typo in challenge#1 It should be @Route("/user/profile", name:"app_user_profile") instead of @Route("/user/profile", name="app_user_profile").
But well, I think everyone understood :)