Estas en: Home > plantilla

Entradas etiquetadas con plantilla

Cron Job WordPress

WordPress 3.x para desarrolladores: Temas y plantillas, sidebar.php y sidebar-footer.php

0

Ya hemos creado casi todas las partes importantes que necesita la página principal, pero aun nos quedan algunas cosas más por crear.

 

SIDEBAR.PHP

Como expliqué en el post anterior, nuestro tema hace dos llamadas a get_sidebar(). La primera se realiza en index.php, y la segunda en footer.php pero pasando a la función un argumento, en este caso ‘footer‘. Este argumento permite a WordPress buscar una plantilla diferente para sidebar que no sea sidebar.php, en nuestro caso necesitará sidebar-footer.php. Si WordPress no encontrase esta plantilla, cargaría la plantilla principal para el sidebar: sidebar.php.

Creamos el archivo sidebar.php y añadimos el siguiente código:

[codesyntax lang=»php»]

		<div id="secondary" class="widget-area" role="complementary">
			<?php if ( ! dynamic_sidebar( 'sidebar-1' ) ) : ?>

				<aside id="archives" class="widget">
					<h3 class="widget-title"><?php _e( 'Archives', 'newtheme' ); ?></h3>
					<ul>
						<?php wp_get_archives( array( 'type' => 'monthly' ) ); ?>
					</ul>
				</aside>

				<aside id="meta" class="widget">
					<h3 class="widget-title"><?php _e( 'Meta', 'newtheme' ); ?></h3>
					<ul>
						<?php wp_register(); ?>
						<li><?php wp_loginout(); ?></li>
						<?php wp_meta(); ?>
					</ul>
				</aside>

			<?php endif; // end sidebar widget area ?>
		</div><!-- #secondary .widget-area -->

[/codesyntax]

El código es bastante sencillo, abrimos una nueva capa que contendrá los widgets que no sean de la sidebar sidebar-1. Como puedes ver hay un condicional que hace esto mismo, utilizando la función dynamic_sidebar( ‘sidebar-1’ ). Esta función comprueba si hay widgets o no en la sidebar que le indiquemos. Según el código, si no hay widgets añadimos dos a la columna. El primero está dentro de la etiqueta aside. Esta etiqueta pertenece a HTML5 y se utiliza para crear bloques de contenido tangencial, dicho de otra forma, sirve para crear bloques con contenido que tengan alguna relación con el contenido de la página (una cita del texto, publicidad, una imagen, etc.). Seguimos.

Dentro del bloque aside encontramos el título del bloque, en este caso «Archives» y una lista que se genera con la función wp_get_archives(). Esta función crea un listado de links, en nuestro caso mostrará los meses y el año en los que haya algún post publicado. Para más información sobre este método, lo mejor es que acudas a la fuente http://codex.wordpress.org/Function_Reference/wp_get_archives, ahí te explican todas las opciones que tienes para generar ese listado.

El segundo bloque aside nos muestra una serie de vínculos para registrarnos (siempre que el registro de usuarios esté activo) y/o identificarnos. Por último tenemos la función wp_meta() que permitirá a otros plugins añadir más vínculos a la lista.

 

SIDEBAR-FOOTER.PHP

Ahora vamos a crear los sidebars del pie de la página, para ello creamos el archivo sidebar-footer.php

WordPress nos permite crear plantillas para partes concretas del tema, como por ejemplo estos sidebar que vamos a crear, para ello existe una jerarquía que WordPress siempre respeta, de tal manera que si la plantilla que se le pide no existe busca la siguiente en esa jerarquía.

Aquí teneis un esquema con la jerarquía que sigue WordPress para el contenido: http://codex.wordpress.org/images/1/18/Template_Hierarchy.png

Dicho esto, vamos a crear la plantilla. Creamos el archivo sidebar-footer.php y añadimos el siguiente código:

[codesyntax lang=»php»]

<?php
	/* The footer widget area is triggered if any of the areas
	 * have widgets. So let's check that first.
	 *
	 * If none of the sidebars have widgets, then let's bail early.
	 */
	if (   ! is_active_sidebar( 'sidebar-3'  )
		&& ! is_active_sidebar( 'sidebar-4' )
		&& ! is_active_sidebar( 'sidebar-5'  )
	)
		return;
	// If we get this far, we have widgets. Let do this.
?>
<div id="supplementary" <?php newtheme_footer_sidebar_class(); ?>>
	<?php if ( is_active_sidebar( 'sidebar-3' ) ) : ?>
	<div id="first" class="widget-area" role="complementary">
		<?php dynamic_sidebar( 'sidebar-3' ); ?>
	</div><!-- #first .widget-area -->
	<?php endif; ?>

	<?php if ( is_active_sidebar( 'sidebar-4' ) ) : ?>
	<div id="second" class="widget-area" role="complementary">
		<?php dynamic_sidebar( 'sidebar-4' ); ?>
	</div><!-- #second .widget-area -->
	<?php endif; ?>

	<?php if ( is_active_sidebar( 'sidebar-5' ) ) : ?>
	<div id="third" class="widget-area" role="complementary">
		<?php dynamic_sidebar( 'sidebar-5' ); ?>
	</div><!-- #third .widget-area -->
	<?php endif; ?>
</div><!-- #supplementary -->

[/codesyntax]

En primer lugar se comprueba si alguno de los tres sidebars está activo, sino se devuelve un return para dar por finalizado el script y que no se genere código html.

En el caso de que alguno, varios o todos los sidebars estén activos se crean sus respectivos bloques, primero comprobando que el sidebar correspondiente está activo, y después cargando los widgets del sidebar con la función dynamic_sidebar( ‘nombre-del-sidebar’ ).

En la capa que alberga los diferentes sidebars se hace una llamada a newtheme_footer_sidebar_class(), esta función la crearemos más adelante en el archivo functions.php, y principalmente lo que hace es crear el atributo class de la capa y su correspondiente valor.

Ahora que ya empezamos a ver algo de contenido, vamos a añadir los estilos. Aquí te dejo a tu elección que hacer, si crearlos tu a mano desde cero o copiar los estilos del tema Twenty Eleven, ya que serían los que se utilizarían para el tema que estamos creando. En cualquier caso solo necesitas, de momento, los estilos del archivo style.css, el resto los iremos añadiendo con posterioridad.

Cron Job WordPress

WordPress 3.x para desarrolladores: Temas y plantillas, index.php y content.php

0

Con el anterior post os dejé un poco colgados con el tutorial, expliqué las plantillas más básicas y la creación de las plantillas de la cabecera y el pie, además de la explicación del código de cada una. Pero aun falta la parte más importante de todas, el contenido.

 

EL BUCLE ( THE LOOP )

Bueno, vamos al lío y explico esto del bucle. En el archivo index.php añadimos el siguiente código entre wp_head() y wp_footer().

 

[codesyntax lang=»php»]

<div id="primary">
			<div id="content" role="main">

			<?php if ( have_posts() ) : ?>

				<?php newtheme_content_nav( 'nav-above' ); ?>

				<?php /* Start the Loop */ ?>
				<?php while ( have_posts() ) : the_post(); ?>

					<?php get_template_part( 'content', get_post_format() ); ?>

				<?php endwhile; ?>

				<?php newtheme_content_nav( 'nav-below' ); ?>

			<?php else : ?>

				<article id="post-0" class="post no-results not-found">
					<header class="entry-header">
						<h1 class="entry-title"><?php _e( 'Nothing Found', 'newtheme' ); ?></h1>
					</header><!-- .entry-header -->

					<div class="entry-content">
						<p><?php _e( 'Apologies, but no results were found for the requested archive. Perhaps searching will help find a related post.', 'newtheme' ); ?></p>
					</div><!-- .entry-content -->
				</article><!-- #post-0 -->

			<?php endif; ?>

			</div><!-- #content -->
		</div><!-- #primary -->

<?php get_sidebar(); ?>

[/codesyntax]

 

Lo primero que hacemos es crear dos capas con id primary y content, ambas contendrán el contenido que se muestre en la página.

Seguidamente tenemos un condicional que comprueba si hay posts para mostrar en la página.

Si es que sí hay posts, WordPress procesará las cinco siguientes líneas de código y dentro de estas nuestro bucle o The Loop.

Antes y después del bucle se hace una llamada a la función newtheme_content_nav(), este es un hook para crear el paginador de post en el caso de que haya más que las que pueden entrar en una página. Esta función la crearemos más adelante en el archivo functions.php.

El bucle while se ejecutará mientras have_posts() sea true, y los datos del post se obtienen de the_post(), que serán procesados en la plantilla correspondiente utilizando get_template_part( ‘content’, get_post_format() ). Esta función (get_template_part()) llama a la plantilla content para procesarla y generar el código html correspondiente.

Si no hay posts entonces se muestra un mensaje al usuario indicando esto mismo.

Cerramos las etiquetas div. Por último nos encontramos con la función get_sidebar(), que nos generará la barra lateral con los widgets de nuestro blog. De hecho ya vimos esta función en la plantilla del pie (footer.php) en ella nos encontramos con la función get_sidebar( ‘footer’ ). La razón de que una función tenga argumento y otra no, radica en la plantilla a usar. En el caso del sidebar del pie, se utilizará sidebar-footer.php y para el sidebar del index.php usaremos la genérica: sidebar.php.

Si ejecutásemos ahora la página principal de nuestro WordPress no veríamos contenido, la razón es que aun no hemos creado la plantilla que muestra el contenido, así que vamos a ello.

 

CONTENT.PHP

Este archivo es el encargado de mostrar el contenido de los posts y maquetarlo en html. Para ello vamos a crear el archivo content.php y añadir las siguientes líneas de código:

 

[codesyntax lang=»php»]

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
		<header class="entry-header">
			<?php if ( is_sticky() ) : ?>
				<hgroup>
					<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
					<h3 class="entry-format"><?php _e( 'Featured', 'newtheme' ); ?></h3>
				</hgroup>
			<?php else : ?>
			<h1 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h1>
			<?php endif; ?>

			<?php if ( 'post' == get_post_type() ) : ?>
			<div class="entry-meta">
				<?php newtheme_posted_on(); ?>
			</div><!-- .entry-meta -->
			<?php endif; ?>

			<?php if ( comments_open() && ! post_password_required() ) : ?>
			<div class="comments-link">
				<?php comments_popup_link( '<span class="leave-reply">' . __( 'Reply', 'newtheme' ) . '</span>', _x( '1', 'comments number', 'newtheme' ), _x( '%', 'comments number', 'newtheme' ) ); ?>
			</div>
			<?php endif; ?>
		</header><!-- .entry-header -->

		<?php if ( is_search() ) : // Only display Excerpts for Search ?>
		<div class="entry-summary">
			<?php the_excerpt(); ?>
		</div><!-- .entry-summary -->
		<?php else : ?>
		<div class="entry-content">
			<?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'newtheme' ) ); ?>
			<?php wp_link_pages( array( 'before' => '<div class="page-link"><span>' . __( 'Pages:', 'newtheme' ) . '</span>', 'after' => '</div>' ) ); ?>
		</div><!-- .entry-content -->
		<?php endif; ?>

		<footer class="entry-meta">
			<?php $show_sep = false; ?>
			<?php if ( 'post' == get_post_type() ) : // Hide category and tag text for pages on Search ?>
			<?php
				/* translators: used between list items, there is a space after the comma */
				$categories_list = get_the_category_list( __( ', ', 'newtheme' ) );
				if ( $categories_list ):
			?>
			<span class="cat-links">
				<?php printf( __( '<span class="%1$s">Posted in</span> %2$s', 'newtheme' ), 'entry-utility-prep entry-utility-prep-cat-links', $categories_list );
				$show_sep = true; ?>
			</span>
			<?php endif; // End if categories ?>
			<?php
				/* translators: used between list items, there is a space after the comma */
				$tags_list = get_the_tag_list( '', __( ', ', 'newtheme' ) );
				if ( $tags_list ):
				if ( $show_sep ) : ?>
			<span class="sep"> | </span>
				<?php endif; // End if $show_sep ?>
			<span class="tag-links">
				<?php printf( __( '<span class="%1$s">Tagged</span> %2$s', 'newtheme' ), 'entry-utility-prep entry-utility-prep-tag-links', $tags_list );
				$show_sep = true; ?>
			</span>
			<?php endif; // End if $tags_list ?>
			<?php endif; // End if 'post' == get_post_type() ?>

			<?php if ( comments_open() ) : ?>
			<?php if ( $show_sep ) : ?>
			<span class="sep"> | </span>
			<?php endif; // End if $show_sep ?>
			<span class="comments-link"><?php comments_popup_link( '<span class="leave-reply">' . __( 'Leave a reply', 'newtheme' ) . '</span>', __( '<b>1</b> Reply', 'nwtheme' ), __( '<b>%</b> Replies', 'newtheme' ) ); ?></span>
			<?php endif; // End if comments_open() ?>

			<?php edit_post_link( __( 'Edit', 'newtheme' ), '<span class="edit-link">', '</span>' ); ?>
		</footer><!-- #entry-meta -->
	</article><!-- #post-<?php the_ID(); ?> -->

[/codesyntax]

 

Sí, es mucho código pero como siempre os lo explicaré casi línea por línea.

En primer lugar tenemos las etiquetas article y header del post:

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
 <header class="entry-header">

Aquí vemos dos funciones de WordPress, la primera the_ID() sirve para devolver el id del post, el segundo genera las clases de estilos para el post.

Ha continuación tenemos el siguiente bloque condicional dentro de la etiqueta header:

 

[codesyntax lang=»php»]

<?php if ( is_sticky() ) : ?>
				<hgroup>
					<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
					<h3 class="entry-format"><?php _e( 'Featured', 'newtheme' ); ?></h3>
				</hgroup>
			<?php else : ?>
			<h1 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h1>
			<?php endif; ?>

			<?php if ( 'post' == get_post_type() ) : ?>
			<div class="entry-meta">
				<?php newtheme_posted_on(); ?>
			</div><!-- .entry-meta -->
			<?php endif; ?>

			<?php if ( comments_open() && ! post_password_required() ) : ?>
			<div class="comments-link">
				<?php comments_popup_link( '<span class="leave-reply">' . __( 'Reply', 'newtheme' ) . '</span>', _x( '1', 'comments number', 'newtheme' ), _x( '%', 'comments number', 'newtheme' ) ); ?>
			</div>
			<?php endif; ?>

[/codesyntax]

 

Como puedes ver el condicional comprueba la función is_sticky(). Esta función comprueba si el post ha sido seleccionado para que se mantenga fijo en la página principal o como destacado. Como verás, si el post está fijo en la página principal se mostrará el título de la entrada y un texto (Featured o Destacado) que indica el estado de este.

En el caso que no sea un post destacado se genera el título por defecto. Para generar la url se utiliza la función the_permalink() que genera la url absoluta del post. Además se añade al atributo title del link el título del post.

[codesyntax lang=»php»]

			<?php if ( 'post' == get_post_type() ) : ?>
			<div class="entry-meta">
				<?php newtheme_posted_on(); ?>
			</div><!-- .entry-meta -->
			<?php endif; ?>

[/codesyntax]

Este código genera el html correspondiente para las etiquetas meta de la página/post: fecha/hora, autor, descripción, etc.

[codesyntax lang=»php»]

			<?php if ( comments_open() && ! post_password_required() ) : ?>
			<div class="comments-link">
				<?php comments_popup_link( '<span class="leave-reply">' . __( 'Reply', 'newtheme' ) . '</span>', _x( '1', 'comments number', 'newtheme' ), _x( '%', 'comments number', 'newtheme' ) ); ?>
			</div>
			<?php endif; ?>

[/codesyntax]

Aquí se comprueba si el post permite comentarios y no es requerida una contraseña. Dentro del condicional se crea el link que mostrará los comentarios, además el texto del vínculo será el número de comentarios que tiene el post. Esto crearía un número al lado del título del post, normalmente con un fondo con una burbuja de diálogo.

[codesyntax lang=»php»]

		<?php if ( is_search() ) : // Only display Excerpts for Search ?>
		<div class="entry-summary">
			<?php the_excerpt(); ?>
		</div><!-- .entry-summary -->
		<?php else : ?>
		<div class="entry-content">
			<?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'newtheme' ) ); ?>
			<?php wp_link_pages( array( 'before' => '<div class="page-link"><span>' . __( 'Pages:', 'newtheme' ) . '</span>', 'after' => '</div>' ) ); ?>
		</div><!-- .entry-content -->
		<?php endif; ?>

[/codesyntax]

Se comprueba si lo que se está mostrando es una búsqueda, si es así se carga parte del cuerpo del post pero añadiendo al final del texto […].

Si no se está mostrando una búsqueda se carga el contenido con la función the_content(), que en el caso que el post contenga un separador del tipo «read more… » se mostrará un texto que lo indique. Por último se muestran una serie de links para poder ir directamente a las diferentes páginas del post.

[codesyntax lang=»php»]

		<footer class="entry-meta">
			<?php $show_sep = false; ?>
			<?php if ( 'post' == get_post_type() ) : // Hide category and tag text for pages on Search ?>
			<?php
				/* translators: used between list items, there is a space after the comma */
				$categories_list = get_the_category_list( __( ', ', 'newtheme' ) );
				if ( $categories_list ):
			?>
			<span class="cat-links">
				<?php printf( __( '<span class="%1$s">Posted in</span> %2$s', 'newtheme' ), 'entry-utility-prep entry-utility-prep-cat-links', $categories_list );
				$show_sep = true; ?>
			</span>
			<?php endif; // End if categories ?>
			<?php
				/* translators: used between list items, there is a space after the comma */
				$tags_list = get_the_tag_list( '', __( ', ', 'newtheme' ) );
				if ( $tags_list ):
				if ( $show_sep ) : ?>
			<span class="sep"> | </span>
				<?php endif; // End if $show_sep ?>
			<span class="tag-links">
				<?php printf( __( '<span class="%1$s">Tagged</span> %2$s', 'newtheme' ), 'entry-utility-prep entry-utility-prep-tag-links', $tags_list );
				$show_sep = true; ?>
			</span>
			<?php endif; // End if $tags_list ?>
			<?php endif; // End if 'post' == get_post_type() ?>

			<?php if ( comments_open() ) : ?>
			<?php if ( $show_sep ) : ?>
			<span class="sep"> | </span>
			<?php endif; // End if $show_sep ?>
			<span class="comments-link"><?php comments_popup_link( '<span class="leave-reply">' . __( 'Leave a reply', 'newtheme' ) . '</span>', __( '<b>1</b> Reply', 'nwtheme' ), __( '<b>%</b> Replies', 'newtheme' ) ); ?></span>
			<?php endif; // End if comments_open() ?>

			<?php edit_post_link( __( 'Edit', 'newtheme' ), '<span class="edit-link">', '</span>' ); ?>
		</footer><!-- #entry-meta -->

[/codesyntax]

Llegamos al pie del post donde se comprobará primero que lo que se muestra es un post y no una búsqueda, en el caso de ser esto afirmativo se cargan las categorías a la que pertenezca el post y se genera su código html correspondiente.

Después se carga el listado de tags o etiquetas y se genera el código html para mostrarlas.

A continuación mostramos de nuevo el número de comentarios del post.

Por último mostramos el link de editar post, siempre y cuando el usuario tenga permiso para ello.

Cron Job WordPress

WordPress 3.x para desarrolladores: Temas y plantillas, primeros pasos

0

Una vez que conocemos los conceptos básicos de WordPress y la estructura de archivos que tienen los temas, vamos a empezar a crear nuestro propio tema. Para ello vamos a utilizar el tema Twenty Elevencomo modelo, iré extrayendo partes del código de este tema y pegándolas en el nuestro, de tal forma que pueda explicar el funcionamiento del código y así poder aprender a crear un tema desde cero.

 

EL TEMA MÁS BÁSICO

Como vimos en el post anterior, el tema más básico que se puede crear en WordPress es el que disponga de los archivos style.css e index.php (en caso de un tema hijo solo sería necesario el archivo style.css, pero eso lo explicaré más adelante). Por tanto vamos a crearlos. Doy por hecho que ya tienes instalado y configurado WordPress en tu entorno de desarrollo, lo único que vamos hacer es activar la muestra de avisos de WordPress durante el desarrollo. Abre el archivo wp-config.php, busca la constante WP_DEBUG y ponla a true.

define('WP_DEBUG', true);

Una vez hecho esto creamos la carpeta de nuestro tema el cual llamaremos newtheme: wp-content/themes/newtheme. A continuación creamos el archivo style.css y añadimos los datos que WordPressnecesita para mostrar el tema en el listado de temas.

/*
Theme Name: New Theme
Theme URI: http://localhost/newtheme
Author: Interadictos.es
Author URI: http://interadictos.es
Description: Primer desarrollo de un tema
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: basic, white
Text Domain: newtheme
*/

Ahora creamos el archivo index.phpy le añadiremos una única linea de código:

[codesyntax lang=»php»]

<?php echo "Hola mundo"; ?>

[/codesyntax]

Nos vamos a la administración de nuestro WordPressy activamos nuestro tema. Si se ha hecho correctamente nos aparecerá el siguiente texto cuando accedamos a la página principal del blog:

Hola mundo

Ya sé, ya sé, este tema no muestra nada, en realidad acabamos de conocer como crear el tema y hacer que se muestre en la administración para poder activarlo. Podríamos seguir añadiendo código al archivo index.php, pero estaríamos creando algo que a la larga nos resultaría difícil de mantener. Por tanto vamos a dividir nuestro tema en partes para poder trabajar mejor con él.

 

CREANDO PLANTILLAS

Habitualmente una página web podemos separarla en tres partes: cabecera, cuerpo y pie. En WordPress ocurre lo mismo, de hecho, WordPressnos va a facilitar la tarea de dividir una página ya que dispone de varios métodos creados exclusivamente para ello.

  • get_header(): Devuelve la plantilla de la cabecera ya procesada.
  • get_footer(): Devuelve la plantilla del pie ya procesada.

Como verás no hay un método como tal para devolver la plantilla del contenido, pero esto lo veremos un poquito más adelante. Vamos a modificar el archivo index.phppara añadir estos dos métodos.

[codesyntax lang=»php»]

<?php get_header(); ?>

<?php get_footer(); ?>

[/codesyntax]

Ahora vamos a crear dos plantillas nuevas que se corresponderán con la cabecera de la página y el pie. Lo llamaremos header.php y footer.php.

 

HEADER.PHP

En header.phpañadimos el siguiente código:

[codesyntax lang=»php»]

<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" <?php language_attributes(); ?>>
<![endif]-->
<!--[if IE 7]>
<html id="ie7" <?php language_attributes(); ?>>
<![endif]-->
<!--[if IE 8]>
<html id="ie8" <?php language_attributes(); ?>>
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8)  ]><!-->
<html <?php language_attributes(); ?>>
<!--<![endif]-->
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<meta name="viewport" content="width=device-width" />
<title><?php
	/*
	 * Print the <title> tag based on what is being viewed.
	 */
	global $page, $paged;

	wp_title( '|', true, 'right' );

	// Add the blog name.
	bloginfo( 'name' );

	// Add the blog description for the home/front page.
	$site_description = get_bloginfo( 'description', 'display' );
	if ( $site_description && ( is_home() || is_front_page() ) )
		echo " | $site_description";

	// Add a page number if necessary:
	if ( $paged >= 2 || $page >= 2 )
		echo ' | ' . sprintf( __( 'Page %s', 'newtheme' ), max( $paged, $page ) );

	?></title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>" />
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
<!--[if lt IE 9]>
<script src="<?php echo get_template_directory_uri(); ?>/js/html5.js" type="text/javascript"></script>
<![endif]-->
<?php
	/* We add some JavaScript to pages with the comment form
	 * to support sites with threaded comments (when in use).
	 */
	if ( is_singular() && get_option( 'thread_comments' ) )
		wp_enqueue_script( 'comment-reply' );

	/* Always have wp_head() just before the closing </head>
	 * tag of your theme, or you will break many plugins, which
	 * generally use this hook to add elements to <head> such
	 * as styles, scripts, and meta tags.
	 */
	wp_head();
?>
</head>

<body <?php body_class(); ?>>

[/codesyntax]

Antes de seguir explicaré un poco el código. Este código es un extracto del archivo header.php del tema twentyeleven que viene incluido con WordPress y que me ha parecido muy bueno para poder utilizarlo como ejemplo. En primer lugar nos encontramos con esto:

<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" <?php language_attributes(); ?>>
<![endif]-->
<!--[if IE 7]>
<html id="ie7" <?php language_attributes(); ?>>
<![endif]-->
<!--[if IE 8]>
<html id="ie8" <?php language_attributes(); ?>>
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html <?php language_attributes(); ?>>
<!--<![endif]-->

language_attributes() devuelve varios atributos de la etiqueta html, más concretamente el idioma y la dirección del texto. En este caso, además, se cuadriplica para poder diferenciar cada versión de Internet Explorer y del resto de navegadores. A continuación tenemos el inicio de la cabecera propiamente dicha y las etiquetas meta:

<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<meta name="viewport" content="width=device-width" />

WordPress nos provee de muchos métodos para poder hacernos la vida más fácil. Entre esos métodos se encuentra bloginfo() que nos devolverá varios datos referentes al blog que estamos creando. Ver más sobre bloginfo()http://codex.wordpress.org/Function_Reference/bloginfo La metaetiqueta llamada viewport es utiliza para indicarle a los navegadores móviles el tamaño de la página. Más info en: http://www.htmlcinco.com/etiqueta-meta-viewport-web-movil/Seguidamente tenemos el título de la página:

[codesyntax lang=»php»]

<title><?php
	/*
	 * Print the <title> tag based on what is being viewed.
	 */
	global $page, $paged;

	wp_title( '|', true, 'right' );

	// Add the blog name.
	bloginfo( 'name' );

	// Add the blog description for the home/front page.
	$site_description = get_bloginfo( 'description', 'display' );
	if ( $site_description && ( is_home() || is_front_page() ) )
		echo " | $site_description";

	// Add a page number if necessary:
	if ( $paged >= 2 || $page >= 2 )
		echo ' | ' . sprintf( __( 'Page %s', 'newtheme' ), max( $paged, $page ) );

	?></title>

[/codesyntax]

Primero recupera dos variables globales $page y $paged, que se refieren a la página y el número de páginas en que esté dividido el contenido. Después utiliza el método wp_title() para mostrar el título de la página o post. Esto le indica a WordPress que muestre el título del post o la página y añada un separador «|» al final (derecha) del título.

A continuación se añade el nombre del blog con bloginfo( ‘name’ ). Se recupera la descripción del sitio utilizando get_bloginfo(), se comprueba si existe esa descripción y si la página que se va a mostrar es el homeo la página principal, y se muestra la descripción. Acto seguido se comprueba el número de página en el que se encuentra el usuario y se muestra. Una vez que se procesa el título tenemos las siguientes etiquetas:

<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>" />
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
<!--[if lt IE 9]>
<script src="<?php echo get_template_directory_uri(); ?>/js/html5.js" type="text/javascript"></script>
<![endif]-->

La primera línea si no recuerdo mal está relacionado con el SEO para los buscadores, a la hora de desarrollar no nos afectará.

La segunda linea nos indica el archivo css para la página, en este caso se utiliza bloginfo( ‘stylesheet_url’ ) para recuperar la url del archivo de estilo style.css.

La tercera línea indica al navegador la ruta para el archivo de pingback, es decir el archivo que se dedicará a recibir las notificaciones de otros autores cuando linken a una página de tu blog.

Las últimas lineas son exclusivas para IE9, que como todas las versiones de Internet Explorer siempre hay algo especial que ponerle a cada uno. En este caso es un pequeño código js para HTML5. Recuerda que este archivo aun no está en nuestro tema. Tendrás que crear una carpeta llamada js, y copiar el archivo desde el tema twentyeleven hasta tu tema dentro de la carpeta que acabas de crear. Por último en nuestro archivo header.phpnos encontramos con lo siguiente:

[codesyntax lang=»php»]

<?php
	/* We add some JavaScript to pages with the comment form
	 * to support sites with threaded comments (when in use).
	 */
	if ( is_singular() && get_option( 'thread_comments' ) )
		wp_enqueue_script( 'comment-reply' );

	/* Always have wp_head() just before the closing </head>
	 * tag of your theme, or you will break many plugins, which
	 * generally use this hook to add elements to <head> such
	 * as styles, scripts, and meta tags.
	 */
	wp_head();
?>
</head>

<body <?php body_class(); ?>>

[/codesyntax]

El pequeño script de php tiene un condicional que lo que hace es añadir un pequeño JavaScript en el caso de que los comentarios estén configurados como hilos. Utilizando wp_enqueue_script( ‘comment-reply’ ) le estamos diciendo a WordPress que carge ahí el archivo wp-include/js/comment-reply.js. Como puedes observar, se llama a la función wp_head(). Esto permite a los plugins poder añadir las cabeceras que ellos consideren oportuno.

Por último cerramos la etiqueta head y abrimos body en la que añadiremos las clases correspondientes a través de la función body_class.

Añadimos el siguiente código justo debajo de la etiqueta body:

[codesyntax lang=»php»]

<div id="page" class="hfeed">
	<header id="branding" role="banner">
			<hgroup>
				<h1 id="site-title"><span><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></span></h1>
				<h2 id="site-description"><?php bloginfo( 'description' ); ?></h2>
			</hgroup>

			<?php
				// Check to see if the header image has been removed
				$header_image = get_header_image();
				if ( $header_image ) :
					// Compatibility with versions of WordPress prior to 3.4.
					if ( function_exists( 'get_custom_header' ) ) {
						// We need to figure out what the minimum width should be for our featured image.
						// This result would be the suggested width if the theme were to implement flexible widths.
						$header_image_width = get_theme_support( 'custom-header', 'width' );
					} else {
						$header_image_width = HEADER_IMAGE_WIDTH;
					}
					?>
			<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
				<?php
					// The header image
					// Check if this is a post or page, if it has a thumbnail, and if it's a big one
					if ( is_singular() && has_post_thumbnail( $post->ID ) &&
							( /* $src, $width, $height */ $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), array( $header_image_width, $header_image_width ) ) ) &&
							$image[1] >= $header_image_width ) :
						// Houston, we have a new header image!
						echo get_the_post_thumbnail( $post->ID, 'post-thumbnail' );
					else :
						// Compatibility with versions of WordPress prior to 3.4.
						if ( function_exists( 'get_custom_header' ) ) {
							$header_image_width  = get_custom_header()->width;
							$header_image_height = get_custom_header()->height;
						} else {
							$header_image_width  = HEADER_IMAGE_WIDTH;
							$header_image_height = HEADER_IMAGE_HEIGHT;
						}
						?>
					<img src="<?php header_image(); ?>" width="<?php echo $header_image_width; ?>" height="<?php echo $header_image_height; ?>" alt="" />
				<?php endif; // end check for featured image or standard header ?>
			</a>
			<?php endif; // end check for removed header image ?>

			<?php
				// Has the text been hidden?
				if ( 'blank' == get_header_textcolor() ) :
			?>
				<div class="only-search<?php if ( $header_image ) : ?> with-image<?php endif; ?>">
				<?php get_search_form(); ?>
				</div>
			<?php
				else :
			?>
				<?php get_search_form(); ?>
			<?php endif; ?>

			<nav id="access" role="navigation">
				<h3 class="assistive-text"><?php _e( 'Main menu', 'newtheme' ); ?></h3>
				<?php /* Allow screen readers / text browsers to skip the navigation menu and get right to the good stuff. */ ?>
				<div class="skip-link"><a class="assistive-text" href="#content" title="<?php esc_attr_e( 'Skip to primary content', 'newtheme' ); ?>"><?php _e( 'Skip to primary content', 'newtheme' ); ?></a></div>
				<div class="skip-link"><a class="assistive-text" href="#secondary" title="<?php esc_attr_e( 'Skip to secondary content', 'newtheme' ); ?>"><?php _e( 'Skip to secondary content', 'newtheme' ); ?></a></div>
				<?php /* Our navigation menu. If one isn't filled out, wp_nav_menu falls back to wp_page_menu. The menu assigned to the primary location is the one used. If one isn't assigned, the menu with the lowest ID is used. */ ?>
				<?php wp_nav_menu( array( 'theme_location' => 'primary' ) ); ?>
			</nav><!-- #access -->
	</header><!-- #branding -->

	<div id="main">

[/codesyntax]

Explicaré el código paso a paso:

[codesyntax lang=»php»]

	<header id="branding" role="banner">
			<hgroup>
				<h1 id="site-title"><span><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></span></h1>
				<h2 id="site-description"><?php bloginfo( 'description' ); ?></h2>
			</hgroup>

[/codesyntax]

En primer lugar se abre una etiqueta header y dentro de hgroupse añade el título y la descripción de la página.

[codesyntax lang=»php»]

			<?php
				// Check to see if the header image has been removed
				$header_image = get_header_image();
				if ( $header_image ) :
					// Compatibility with versions of WordPress prior to 3.4.
					if ( function_exists( 'get_custom_header' ) ) {
						// We need to figure out what the minimum width should be for our featured image.
						// This result would be the suggested width if the theme were to implement flexible widths.
						$header_image_width = get_theme_support( 'custom-header', 'width' );
					} else {
						$header_image_width = HEADER_IMAGE_WIDTH;
					}
					?>

[/codesyntax]

Esta parte comprueba que existe una imagen para la cabecera. Si es que sí se crea un condicional para comprobar que la función get_custom_header existe para que el tema sea compatible con versiones de WordPress anterior a la 3.4. En el caso de que existe se utilizará la función get_theme_support para obtener el ancho para la imagen, sino se utilizará la constante HEADER_IMAGE_WIDTH.

Tanto la constante como el ancho se crean en el archivo functions.php que veremos más adelante.

[codesyntax lang=»php»]

			<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
				<?php
					// The header image
					// Check if this is a post or page, if it has a thumbnail, and if it's a big one
					if ( is_singular() && has_post_thumbnail( $post->ID ) &&
							( /* $src, $width, $height */ $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), array( $header_image_width, $header_image_width ) ) ) &&
							$image[1] >= $header_image_width ) :
						// Houston, we have a new header image!
						echo get_the_post_thumbnail( $post->ID, 'post-thumbnail' );
					else :
						// Compatibility with versions of WordPress prior to 3.4.
						if ( function_exists( 'get_custom_header' ) ) {
							$header_image_width  = get_custom_header()->width;
							$header_image_height = get_custom_header()->height;
						} else {
							$header_image_width  = HEADER_IMAGE_WIDTH;
							$header_image_height = HEADER_IMAGE_HEIGHT;
						}
						?>
					<img src="<?php header_image(); ?>" width="<?php echo $header_image_width; ?>" height="<?php echo $header_image_height; ?>" alt="" />
				<?php endif; // end check for featured image or standard header ?>
			</a>

[/codesyntax]

Creamos el vínculo con la url de la página principal, el condicional permite tener compatibilidad con  versiones anteriores a la versión 3.4 de WordPress. Con get_the_post_thumbnailcreamos la imagen en caso de que sea un post o una página, sino obtenemos el ancho y alto de la imagen y creamos la etiqueta correspondiente.

[codesyntax lang=»php»]

			<?php
				// Has the text been hidden?
				if ( 'blank' == get_header_textcolor() ) :
			?>
				<div class="only-search<?php if ( $header_image ) : ?> with-image<?php endif; ?>">
				<?php get_search_form(); ?>
				</div>
			<?php
				else :
			?>
				<?php get_search_form(); ?>
			<?php endif; ?>

[/codesyntax]

Aquí se comprueba el color de texto de la cabecera, si es blanco (blank) se crea una capa con el formulario de búsqueda dentro, si no solo se añade el formulario de búsqueda. El color de texto de la cabecera se configura en functions.php.

[codesyntax lang=»php»]

			<nav id="access" role="navigation">
				<h3 class="assistive-text"><?php _e( 'Main menu', 'newtheme' ); ?></h3>
				<?php /* Allow screen readers / text browsers to skip the navigation menu and get right to the good stuff. */ ?>
				<div class="skip-link"><a class="assistive-text" href="#content" title="<?php esc_attr_e( 'Skip to primary content', 'newtheme' ); ?>"><?php _e( 'Skip to primary content', 'newtheme' ); ?></a></div>
				<div class="skip-link"><a class="assistive-text" href="#secondary" title="<?php esc_attr_e( 'Skip to secondary content', 'newtheme' ); ?>"><?php _e( 'Skip to secondary content', 'newtheme' ); ?></a></div>
				<?php /* Our navigation menu. If one isn't filled out, wp_nav_menu falls back to wp_page_menu. The menu assigned to the primary location is the one used. If one isn't assigned, the menu with the lowest ID is used. */ ?>
				<?php wp_nav_menu( array( 'theme_location' => 'primary' ) ); ?>
			</nav><!-- #access -->

[/codesyntax]

Por último se añade el menú superior de las páginas.

 

FOOTER.PHP

Añadimos el siguiente código al archivo footer.php: 

[codesyntax lang=»php»]

	</div><!-- #main -->

	<footer id="colophon" role="contentinfo">

			<?php
				/* A sidebar in the footer? Yep. You can can customize
				 * your footer with three columns of widgets.
				 */
				if ( ! is_404() )
					get_sidebar( 'footer' );
			?>

			<div id="site-generator">
				<?php do_action( 'newtheme_credits' ); ?>
				<a href="<?php echo esc_url( __( 'http://interadictos.es/', 'newtheme' ) ); ?>" title="<?php esc_attr_e( 'Semantic Personal Publishing Platform', 'newtheme' ); ?>" rel="generator"><?php printf( __( 'Proudly powered by %s', 'newtheme' ), 'interadictos.es' ); ?></a>
			</div>
	</footer><!-- #colophon -->
</div><!-- #page -->

<?php wp_footer(); ?>

</body>
</html>

[/codesyntax]

En este archivo se cierran las etiquetas que contienen la mayor parte del contenido de la página, se añaden los sidebar (que veremos más adelante) del pie, siempre y cuando no sea una página 404, y se añade el copyright y la información del tema. Por último se añade la función wp_footer que permitirá a los plugins mostrar su propio contenido en el pie de página.

Cron Job WordPress

WordPress 3.x para desarrolladores: Introducción

0

Después de varias semanas buscando información sobre WordPress para un proyecto que tenía pendiente (ya acabado), he observado que hay cierta escasez de información sobre el desarrollo de WordPress, ya que la mayoría de tutoriales o manuales que rondan por internet están limitados a la creación básica de plugins o a lo más básico de la creación de plantillas.

Por ello voy a realizar un tutorial que, basandome en el tema Twenty Eleven de WordPress permita conocer el funcionamiento de los temas y las plantillas. Para desarrollar la parte de los plugins se creará uno de ejemplo.

Muchos ejemplos de código serán de la documentación principal de WordPress y es la que deberías consultar más habitualmente si vas a desarrollar para WordPresshttp://codex.wordpress.org/Main_Page

Durante las próximas semanas publicaré un tema por semana hasta que se complete el tutorial.

Symfony: La vista (IV), mecanismo de escape

0

Este capítulo del libro me está resultando de lo más pesado, principalmente porque no hay mucho con lo que practicar, ya que la mayoría de la información es teoría basada en donde ubicar cada cosa en cada caso. Aunque las posibilidades que ofrece Symfony a medida que te adentras en él, son enormes.

Para acabar con la vista solo queda ver el mecanismo de escape que utiliza Symfony. Empezemos:

Este apartado del libro comienza así:

Cuando se insertan datos generados dinámicamente en una plantilla, se debe asegurar la integridad de los datos. Por ejemplo, si se utilizan datos obtenidos mediante formularios que pueden rellenar usuarios anónimos, existe un gran riesgo de que los contenidos puedan incluir scripts y otros elementos maliciosos que se encargan de realizar ataques de tipo XSS (cross-site scripting). Por tanto, se debe aplicar un mecanismo de escape a todos los datos mostrados, de forma que ninguna etiqueta HTML pueda ser peligrosa.

ACTIVANDO EL MECANISMO DE ESCAPE

Fácil. El mecanismo de escape se activa en el archivo config/settings.yml de la aplicación utilizando para ello dos parámentros:

  • scaping_strategy: Define la forma en la que las variables están disponibles en la vista.
  • scaping_method: Indica la función que se aplica a los datos.

all:
.settings:
escaping_strategy: both
escaping_method: ESC_ENTITIES

Esto de aquí arriba es lo único que tendrás que escribir para activar el mecanismo de escape. Ahora mismo, nuestra aplicación estaría utilizando el método htmlentities() de PHP para escapar los caracteres de html. Más adelante veremos más valores que pueden tener estos parámentros.

Por ejemplo, si tenemos en nuestra acción esta variable:

$this->prueba = ‘<script>alert(document.cookie)</script>’;

Al tener el mecanismo de escape activado, al mostrarla en la plantilla nos dará el siguiente resultado:

echo $prueba;
=> &gt;&lt;script&gt;alert(document.cookie)&lt;/script&gt;

Si se activa el mecanismo de escape, desde cualquier plantilla se puede acceder a una nueva variable llamada $sf_data. Se trata de un objeto contenedor que hace referencia a todas las variables que se han modificado mediante el sistema de escape. De esta forma, también es posible mostrar el contenido de la variable prueba de la siguiente manera:

echo $sf_data->get(‘prueba’);
=> &gt;&lt;script&gt;alert(document.cookie)&lt;/script&gt;

Con esta clase también podemos acceder a los datos de la variable en crudo, es decir, antes de que sus caracteres fuesen escapados:

echo $sf_data->getRaw(‘prueba’);
=> <script>alert(document.cookie)</script>

OPCIONES PARA scaping_strategy

  • backward compatible mode (o modo retrocompatible): el contenido de las variables no se modifica, pero el contenedor $sf_data almacena una versión modificada de cada variable. De esta forma, los datos de las variables se obtienen en crudo, a menos que se obtenga la versión modificada del objeto $sf_data. Se trata del valor por defecto de la opción, aunque se trata del modo que permite los ataques de tipo XSS.
  • both: a todas las variables se les aplica el mecanismo de escape. Los valores también están disponibles en el contenedor $sf_data. Se trata del valor recomendado, ya que solamente se está expuesto al riesgo si se utilizan de forma explícita los datos originales. En ocasiones, se deben utilizar los valores originales, por ejemplo para incluir código HTML de forma que se interprete en el navegador y no se muestre el código HTML. Si una aplicación se encuentra medio desarrollada y se cambia la estrategia del mecanismo de escape a este valor, algunas funcionalidades pueden dejar de funcionar como se espera. Lo mejor es seleccionar esta opción desde el principio.
  • on: los valores solamente están disponibles en el contenedor $sf_data. Se trata del método más seguro y más rapido de manejar el mecanismo de escape, ya que cada vez que se quiere mostrar el contenido de una variable, se debe elegir el método get() para los datos modificados o el método getRaw() para el contenido original. De esta forma, siempre se recuerda la posibilidad de que los datos de la variable sean corruptos.
  • off: deshabilita el mecanismo de escape. Las plantillas no pueden hacer uso del contenedor $sf_data. Si nunca se va a necesitar el sistema de escape, es mejor utilizar esta opción y no la opción por defecto bc, ya que la aplicación se ejecuta más rápidamente.

OPCIONES PARA scaping_method

  • ESC_RAW: no modifica el valor original.
  • ESC_ENTITIES: aplica la función htmlentities() de PHP al valor que se le pasa y utiliza la opción ENT_QUOTES para el estilo de las comillas.
  • ESC_JS: modifica un valor que corresponde a una cadena de JavaScript que va a ser utilizada como HTML. Se trata de una opción muy útil para escapar valores cuando se emplea JavaScript para modificar de forma dinámica el contenido HTML de la página.
  • ESC_JS_NO_ENTITIES: modifica un valor que va a ser utilizado en una cadena de JavaScript pero no le añade las entidades HTML correspondientes. Se trata de una opción muy útil para los valores que se van a mostrar en los cuadros de diálogo (por ejemplo para una variable llamada miCadena en la instrucción javascript:alert(miCadena);).

APLICANDO EL MECANISMO DE ESCAPE A ARRAYS Y OBJETOS

// Definición de la clase
class miClase
{
public function pruebaCaracterEspecial($valor = »)
{
return ‘<‘.$valor.’>’;
}
}

// En la acción
$this->array_prueba = array(‘&’, ‘<‘, ‘>’);
$this->array_de_arrays = array(array(‘&’));
$this->objeto_prueba = new miClase();

// En la plantilla
<?php foreach($array_prueba as $valor): ?>
<?php echo $valor ?>
<?php endforeach; ?>
=> &amp; &lt; &gt;
<?php echo $array_de_arrays[0][0] ?>
=> &amp;
<?php echo $objeto_prueba->pruebaCaracterEspecial(‘&’) ?>
=> &lt;&amp;&gt;

Los métodos de los objetos a los que se aplica el mecanismo de escape aceptan un parámetro adicional:

<?php echo $objeto_prueba->pruebaCaracterEspecial(‘&’) ?>
=> &lt;&amp;&gt;
// Las siguientes 3 líneas producen el mismo resultado
<?php echo $objeto_prueba->pruebaCaracterEspecial(‘&’, ESC_RAW) ?>
<?php echo $sf_data->getRaw(‘objeto_prueba’)->pruebaCaracterEspecial(‘&’) ?>
<?php echo $sf_data->get(‘objeto_prueba’, ESC_RAW)->pruebaCaracterEspecial(‘&’) ?>
=> <&>

Las variables de Symfony también se modifican al activar el mecanismo de escape. Por tanto, las variables $sf_user, $sf_request, $sf_param y $sf_context siguen funcionando, pero sus métodos devuelven sus datos modificados, a no ser que se utilice la opción ESC_RAW como último argumento de las llamadas a los métodos.

Symfony: La vista (I), fragmentos de código

0

Debido a que la parte de Symfony que explicaré hoy es bastante densa no podré resumir en un solo post todo el capítulo referente a la Vista, por tanto este será el primero de una serie de post sobre la Vista en Symfony que se explica en el manual de Symfony.

La vista

Como ya he comentado en anteriores post, Symfony sigue el sistema de Modelo-Vista-Controlador (MVC) para que la realización de nuestros proyectos estén mucho mejor estructurados y sean más fáciles de comprender por otros programadores.

Symfony para crear las vistas o implementar el diseño que hemos creado a nuestro proyecto, utiliza plantillas, esto son trozos de código html que se unen para formar la página que ha pedido el usuario.

En Symfony todo el diseño se divide de la siguiente manera:

  • Layout: Es la parte del diseño que se mostrará en todas las páginas (cabeceras, pie, menú, etc).
  • Elementos parciales: Si el fragmento contiene poca lógica.
  • Componentes: Si el fragmento tiene mucha lógica o debe acceder a la base de datos.
  • Slots: Si el fragmento va a sustituir a una parte del layout y se mostrará una parte por defecto.

En el libro lo explican bastante bien como se dividen las plantillas, los fragmentos de código que se pueden utilizar, cómo pasar variables desde la acción a los fragmentos de código, y algún detalle más que viene bien conocer. Os dejo el link a los Fragmentos de código.

Normalmente cuando trabajamos con plantillas en nuestros proyectos PHP, utilizamos la instrucción include() y en Symfony podríamos añadir a nuestro código algo como lo siguiente:

<?php include(sfConfig::get(‘sf_app_template_dir’).’/miFragmento.php’) ?>

Pero esta forma de añadir fragmentos de código no es muy limpia y, además, la caché de Symfony no reconoce la instrucción include() con lo que ese fragmento no podría ser cacheado. Aquí es donde entran en juego los fragmentos de código que he comentado anteriormente.

ELEMENTOS PARCIALES

Observa un periódico digital, su portada concretamente, verás que las noticias estan encajadas como en recuadros imaginarios y que cada noticia sigue un patrón: un titular y un pequeño avance de la noticia. Eso es un elemento parcial. Podemos poner ese elemento parcial en cualquier parte de ese periódico digital, ya que siempre será importante que el usuario pueda acceder a otras noticias con un pequeño avance.

Symfony sigue esta misma lógica para los elementos parciales. Estos, al igual que las plantillas, se ubican en la carpeta «templates/» del proyecto y son accesibles desde el módulo en el que se encuentre el archivo, desde otro módulo o desde la carpeta raíz de las plantillas «templates/«. Los elementos parciales se diferencian de las plantillas por llevar un guión bajo al principio del nombre del archivo ( _elementoparcial.php). Veamos como llamar a los elementos parciales desde distintas ubicaciones:

// Incluir el elemento parcial de miaplicacion/modules/mimodulo/templates/_miparcial1.php
// Como la plantilla y el elemento parcial están en el mismo módulo,
// se puede omitir el nombre del módulo
<?php include_partial(‘miparcial1’) ?>

// Incluir el elemento parcial de miaplicacion/modules/otromodulo/templates/_miparcial2.php
// En este caso es obligatorio indicar el nombre del módulo
<?php include_partial(‘otromodulo/miparcial2’) ?>

// Incluir el elemento parcial de miaplicacion/templates/_miparcial3.php
// Se considera que es parte del módulo ‘global’
<?php include_partial(‘global/miparcial3’) ?>

PASANDO VARIABLES AL ELEMENTO PARCIAL

Primero definimos la variable en la acción del módulo llamado mimodulo (mimodulo/actions/actions.class.php)

class mimoduloActions extends sfActions
{
public function executeIndex()
{
$this->total = 100;
}
}

En la plantilla llamamos al elemento parcial con la función include_partial() y le pasamos la variable en mimodulo/templates/indexSuccess.php.

<p>¡Hola Mundo!</p>
<?php include_partial(‘miparcial’, array(‘mitotal’ => $total)
) ?>

De esta manera podremos usar la variable en el elemento parcial en mimodulo/templates/_miparcial.php.

<p>Total: <?php echo $mitotal ?></p>

COMPONENTES

Los componentes son como los módulos, pero más rápidos. Siguen la misma lógica que los módulos y tienen una estructura de archivos parecida. Para nombrar un componente se utiliza la palabra execute seguido del nombre del componente, por ejemplo:

La clase de los componentes, en modules/news/actions/components.class.php

<?php

class newsComponents extends sfComponents
{
public function executeHeadlines()
{
$c = new Criteria();
$c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
$c->setLimit(5);
$this->news = NewsPeer::doSelect($c);
}
}

La parte visual de los componentes se crea utilizando los elementos parciales. Para nombrarlos se usa lo mismo que para los componentes solo que sustituyendo la palabra execute por un guión bajo.

El elemento parcial, en modules/news/templates/_headlines.php

<div>
<h1>Últimas noticias</h1>
<ul>
<?php foreach($news as $headline): ?>
<li>
<?php echo $headline->getPublishedAt() ?>
<?php echo link_to($headline->getTitle(),’news/show?id=’.$headline->getId()) ?>
</li>
<?php endforeach ?>
</ul>
</div>

Cada vez que se quiera añadir el componente a una plantilla, sólo será necesario escribir el siguiente código:

<?php include_component(‘news’, ‘headlines’) ?>

Paso de parámetros a un componente y su plantilla:

// Llamada al componente
<?php include_component(‘news’, ‘headlines’, array(‘parametro’ => ‘valor’)) ?>

// Dentro del componente
echo $this->parametro;
=> ‘valor’

// Dentro del elemento parcial _headlines.php
echo $parametro;
=> ‘valor’

SLOTS

Aquí debería hablaros de los slots que simplemente son una especie de elemento parcial configurable, y para explicároslo solo se me ocurre hacer un copy&paste del libro, así que os dejo el link (al final de la página) y espero que os ayude.

Ir arriba