Creando Aplicaciones Single Page con WordPress y Angular.js
Spanish (Español) translation by Magdiel Cordero (you can also view the original English article)



Trabajar con el framework de Angular.js es rápido y gratificante y combinado con WordPress se puede crear un agradable SPA(Single-page Application) en un corto lapso de tiempo. Con todos los controles y plugins del CMS que WordPress ofrece, se convierte en un atajo interesante.
Configurando el tema
Vamos a empezar creando un nuevo tema usando el tema _tk de boilerplate. Se trata de una aplicación del tema _s subrayado de Automattic pero con Bootstrap de Twitter implementado.
Toma el tema en GitHub y coloque los archivos en su directorio de themes:
1 |
$ cd themes |
2 |
$ wget https://github.com/Themekraft/_tk/archive/master.zip
|
3 |
wp-content/themes/$ unzip master.zip
|
4 |
Archive: master.zip |
5 |
69acda231e2a2f8914374df81b89a7aa37d594fa |
6 |
creating: _tk-master/ |
7 |
inflating: _tk-master/404.php |
8 |
inflating: _tk-master/archive.php |
9 |
inflating: _tk-master/comments.php |
10 |
inflating: _tk-master/content-page.php |
11 |
inflating: _tk-master/content-single.php |
12 |
... |
13 |
## Rename The Directory
|
14 |
$ mv _tk-master/ angular-bootstrap |
15 |
$ rm -f master.zip |
Ahora que ya tenemos el tema de inicial _tk, necesitaremos los paquetes npm, angular y angular-route dentro de nuestro directorio de theme (estamos utilizando el nombre de angular-bootstrap).
1 |
$ cd wp-angular |
2 |
$ npm init
|
3 |
#follow the prompts to create your package.json file
|
4 |
... |
5 |
"author": "", |
6 |
"license": "ISC" |
7 |
}
|
8 |
|
9 |
|
10 |
Is this ok? (yes) yes |
11 |
## Install The Packages
|
12 |
$ $ npm install angular angular-route --save |
- Debe inicializar
npmdentro del directorio themes connpm initpara crear el archivopackage.json, el cualnpmutiliza para administrar proyectos. - Mediante el uso de
--saveen nuestro comandonpm install angular angular-route --save, le estamos diciendo anpmque agregue los módulos como dependencias a nuestro proyecto. - En el futuro, si tenemos que compartir este proyecto con otro desarrollador, sólo necesitan ejecutar
npm installen el mismo directorio donde se encuentre elpackage.jsoncon el fin de obtener los paquetes.
Ahora tendrás los paquetes en el directorio node_modules dentro de tu directorio theme. Echa un vistazo en el directorio y podrás ver varios archivos js. Vamos a usar angular.min.js para el desarrollo
Inicializando Angular
Para incluir angular.min.js en WordPress tenemos que modificar el archivo functions.php para que podamos poner los scripts en WordPress.
En functions.php, encuentra la función de _tk_scripts() y añade lo siguiente al final de la función:
1 |
//Load angular
|
2 |
wp_enqueue_script('angularjs', get_template_directory_uri() .'/node_modules/angular/angular.min.js'); |
3 |
wp_enqueue_script('angularjs-route', get_template_directory_uri() .'/node_modules/angular-route/angular-route.min.js'); |
4 |
wp_enqueue_script('scripts', get_stylesheet_directory_uri() . '/js/scripts.js', array( 'angularjs', 'angularjs-route' )); |
Usted también tendrá que crear js/scripts.js—para esto Ahora crearemos un archivo en blanco.
Ahora actualiza tu tema en un navegador y podrás ver en herramientas para desarrolladores que angular.min.js ahora esta incluido .
Usando Partials
Angular.js tiene un gran sistema para actualizar sólo una parte parcial de código HTML. Para sacar provecho de esto y el módulo de angular-router, necesitamos crear un directorio dentro del tema llamado partials.
1 |
$ mkdir partials |
Dentro del directorio de partials, cree un archivo denominado main.html para pruebas y añadir cualquier HTML interno.
Localizar la ruta de Partials en WordPress
Para que Angular pueda cargar los parciales, debemos proporcionar una dirección URL completa. He tenido algunos problemas utilizando el método de get_stylesheet_directory_uri(), pero pruébalo por ti mismo. Si no funciona, utilice la dirección URL completa.
Agregue lo siguiente a la función _tk_scripts abajo donde añadiste la angularjs y las líneas angular-route desde el último paso:
1 |
// With get_stylesheet_directory_uri()
|
2 |
wp_localize_script('scripts', 'localized', |
3 |
array( |
4 |
'partials' => get_stylesheet_directory_uri() . '/wp-content/themes/angular-bootstrap/partials/' |
5 |
)
|
6 |
);
|
Si esto no funciona (me sucedió cuando lo escribí para mi), escriba en la URL, por ejemplo.
1 |
// With hardcoded value
|
2 |
wp_localize_script('scripts', 'localized', |
3 |
array( |
4 |
'partials' => 'https://www.mydomaind.com/wp-content/themes/angular-bootstrap/partials/' |
5 |
)
|
6 |
);
|
Habilitando WP-API
Para que Angular trabaje con WordPress, tenemos que habilitar el Plugin REST WP-API. Esto es simple, ya que es sólo la instalación de un plugin.
Descargue e instale el plugin desde git y ejecute lo siguiente en su directorio de plugins:
1 |
git clone git@github.com:WP-API/WP-API.git json-rest-api |
Luego active el plugin en el panel de wp-admin. Usted podrá ver un JSON como resultado en wordpress.com/wp-json una vez que se haya habilitado.
Construcción de rutas
Las Rutas componen las páginas específicas de tu blog. Ahora podemos definir una para nuestro main.html parcial — y configurarlo para que se muestre en la página de índice de nuestro WordPress.
Primero garantice que la aplicación de Angular.js se define mediante el atributo ng-app y en header.php haga lo siguiente:
1 |
<!DOCTYPE html>
|
2 |
|
3 |
<html <?php language_attributes(); ?> ng-app="wp"> |
4 |
<head>
|
5 |
<base href="/"> |
Aquí pedimos la aplicación wp con el atributo de ng-app. También hemos creado la etiqueta base para que Angular pueda encontrar el JSON que hemos habilitado en WP-API.
Agregue lo siguiente a js/scripts.js:
1 |
angular.module('wp', ['ngRoute']) |
2 |
.config(function($routeProvider, $locationProvider) { |
3 |
$routeProvider
|
4 |
.when('/', { |
5 |
templateUrl: localized.partials + 'main.html', |
6 |
controller: 'Main' |
7 |
})
|
8 |
})
|
9 |
.controller('Main', function($scope, $http, $routeParams) { |
10 |
$http.get('wp-json/posts/').success(function(res){ |
11 |
$scope.posts = res; |
12 |
});
|
13 |
});
|
Ahora dentro de partials/main.html añada esto:
1 |
<ul>
|
2 |
<li ng-repeat="post in posts"> |
3 |
<a href="{{post.slug}}"> |
4 |
{{post.title}}
|
5 |
</a>
|
6 |
</li>
|
7 |
</ul>
|
Y finalmente dentro de index.php, directamente después de get_header.php(), agregue el atributo Angular ng-view de una etiqueta div.
1 |
<div ng-view></div> |
Actualizar el índice de tu WordPress, y ahora se mostrará una lista de sus entradas de blog en la página de inicio.
Esto es debido al ng-controller que invoca el controlador Main desde scripts.js y el atributo de ng-view especifica donde se debe renderizar Angular.
Mostrando un Post por Slug
Ahora vamos a agregar la ruta para mostrar un blog de WordPress a través de la URL de slug.
Abra js/scripts.js y ajuste el archivo para que se lea como sigue:
1 |
angular.module('wp', ['ngRoute']) |
2 |
.config(function($routeProvider, $locationProvider) { |
3 |
|
4 |
$routeProvider
|
5 |
.when('/', { |
6 |
templateUrl: localized.partials + 'main.html', |
7 |
controller: 'Main' |
8 |
})
|
9 |
.when('/:slug', { |
10 |
templateUrl: localized.partials + 'content.html', |
11 |
controller: 'Content' |
12 |
})
|
13 |
.otherwise({ |
14 |
redirectTo: '/' |
15 |
});
|
16 |
})
|
17 |
.controller('Main', function($scope, $http, $routeParams) { |
18 |
$http.get('wp-json/posts/').success(function(res){ |
19 |
$scope.posts = res; |
20 |
});
|
21 |
})
|
22 |
.controller('Content', |
23 |
['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) { |
24 |
$http.get('wp-json/posts/?filter[name]=' + $routeParams.slug).success(function(res){ |
25 |
$scope.post = res[0]; |
26 |
});
|
27 |
}
|
28 |
]
|
29 |
);
|
Agregando el controlador Content, podemos especificar la URI $http.get para los mensajes JSON y especificar a slug como el parámetro de filtro.
Para crear esto utilizamos el siguiente código: $http.get ('wp-json/posts/?filter[name] =' + $routeParams.slug).
Nota: Para obtener la ruta de trabajo /:slug, se debe especificar /%postname%/ como tu estructura permalink en el wp-admin.
Asegúrese de establecer content.html con lo siguiente:
1 |
<h1>{{post.title}}</h1> |
2 |
{{post.content}}
|
Ahora si actualiza la página, usted podrá navegar a los post de tu blog mediante los enlaces en la lista que hiciste en el paso anterior.
Usando servicios de Angular en WordPress
Hasta ahora hemos visto cómo crear rutas y empezar a trabajar con la API de wp-json. Antes de empezar a escribir cualquier lógica, necesitamos un lugar para ir, y eso está dentro de un Angular service(en este ejemplo utilizamos un servicio Factory).
Crea un nuevo archivo js/services.js y agregue el código siguiente para recuperar post y categorías:
1 |
|
2 |
function ThemeService($http) { |
3 |
|
4 |
var ThemeService = { |
5 |
categories: [], |
6 |
posts: [], |
7 |
pageTitle: 'Latest Posts:', |
8 |
currentPage: 1, |
9 |
totalPages: 1, |
10 |
currentUser: {} |
11 |
};
|
12 |
|
13 |
//Set the page title in the <title> tag
|
14 |
function _setTitle(documentTitle, pageTitle) { |
15 |
document.querySelector('title').innerHTML = documentTitle + ' | AngularJS Demo Theme'; |
16 |
ThemeService.pageTitle = pageTitle; |
17 |
}
|
18 |
|
19 |
//Setup pagination
|
20 |
function _setArchivePage(posts, page, headers) { |
21 |
ThemeService.posts = posts; |
22 |
ThemeService.currentPage = page; |
23 |
ThemeService.totalPages = headers('X-WP-TotalPages'); |
24 |
}
|
25 |
|
26 |
ThemeService.getAllCategories = function() { |
27 |
//If they are already set, don't need to get them again
|
28 |
if (ThemeService.categories.length) { |
29 |
return; |
30 |
}
|
31 |
|
32 |
//Get the category terms from wp-json
|
33 |
return $http.get('wp-json/taxonomies/category/terms').success(function(res){ |
34 |
ThemeService.categories = res; |
35 |
});
|
36 |
};
|
37 |
|
38 |
ThemeService.getPosts = function(page) { |
39 |
return $http.get('wp-json/posts/?page=' + page + '&filter[posts_per_page]=1').success(function(res, status, headers){ |
40 |
ThemeService.posts = res; |
41 |
page = parseInt(page); |
42 |
|
43 |
// Check page variable for sanity
|
44 |
if ( isNaN(page) || page > headers('X-WP-TotalPages') ) { |
45 |
_setTitle('Page Not Found', 'Page Not Found'); |
46 |
} else { |
47 |
//Deal with pagination
|
48 |
if (page>1) { |
49 |
_setTitle('Posts on Page ' + page, 'Posts on Page ' + page + ':'); |
50 |
} else { |
51 |
_setTitle('Home', 'Latest Posts:'); |
52 |
}
|
53 |
|
54 |
_setArchivePage(res,page,headers); |
55 |
}
|
56 |
});
|
57 |
};
|
58 |
|
59 |
return ThemeService; |
60 |
}
|
61 |
|
62 |
//Finally register the service
|
63 |
app.factory('ThemeService', ['$http', ThemeService]); |
64 |
Esta es la configuración básica de un factory, donde tenemos dos funciones internas _setTitle y _setArchivePage. Estos métodos se llaman de getPosts y getCategories para actualizar el título de la página actual y también uno interno para saber que número de página estamos mirando.
Necesitamos comenzar a usar el módulo de ngSanitize para el análisis de entradas a nuestro servicio. Instalar este con npm así dentro del directorio de tu tema:
1 |
$ npm install angular-sanitize --save |
El ThemeService es solo un objeto básico de JavaScript que realiza una búsqueda de categoría a través de $http.get, y como el método getPosts. Ahora haremos que nuestro controlador este pendiente de este servicio. Abra scripts.js y modifique el controlador para que este dependa de ThemeService.
1 |
//Main controller
|
2 |
app.controller('Main', ['$scope', '$http', 'ThemeService', function($scope, $http, ThemeService) { |
3 |
//Get Categories from ThemeService
|
4 |
ThemeService.getAllCategories(); |
5 |
|
6 |
//Get the first page of posts from ThemeService
|
7 |
ThemeService.getPosts(1); |
8 |
|
9 |
$scope.data = ThemeService; |
10 |
}]);
|
Tampoco te olvides de activar el módulo angular-sanitize dentro de scripts.js en la primera línea con:
1 |
var app = angular.module('wp', ['ngRoute', 'ngSanitize']); |
Finalmente usted tendrá que asegurarse de que js/services.js esta empotrado dentro de WordPress así también el módulo angular-sanitize. Modifique el archivo functions.php y anexe lo siguiente antes de la llamada wp_localize_script:
1 |
wp_enqueue_script('angularjs-sanitize', get_stylesheet_directory_uri() . '/node_modules/angular-sanitize/angular-sanitize.min.js'); |
2 |
wp_enqueue_script('theme-service', get_stylesheet_directory_uri() . '/js/services.js'); |
Ahora necesitamos actualizar el main.html parcial para mostrar estas categorías que están siendo proporcionados por el ThemeService.
1 |
<h1>Categories</h1> |
2 |
<ul>
|
3 |
<li ng-repeat="category in data.categories"> |
4 |
<span ng-if="current_category_id && category.ID == current_category_id" ng-bind-html="category.name"></span> |
5 |
<a ng-if="!current_category_id || category.ID != current_category_id" href="category/{{category.slug}}" ng-bind-html="category.name"></a> |
6 |
</li>
|
7 |
</ul>
|
8 |
|
9 |
<p>{{data.pageTitle}}</p> |
10 |
<ul>
|
11 |
<li ng-repeat="post in data.posts"> |
12 |
<a href="/{{post.slug}}" ng-bind-html="post.title"></a> |
13 |
<a href="/{{post.slug}}" ng-if="post.featured_image_thumbnail_url"><img ng-src="{{post.featured_image_thumbnail_url}}" alt="{{post.featured_image.title.rendered}}" /></a> |
14 |
<div ng-bind-html="post.excerpt.rendered"></div> |
15 |
</li>
|
16 |
</ul>
|
Ahora podrás ver tus post y categorías que aparecen en tu página de inicio por ng-view mediante un servicio factory de Angular. La ventaja de esto es que todos los componentes tendrán los datos a su disposición. Así que ahora podemos compartir el objeto categorías entre todos nuestros controladores en nuestras rutas.
Cosas para retomar más adelante
Ahora que tenemos un servicio para nuestro tema, podemos continuar desarrollando la capa de datos e incorporar Bootstrap dentro del sitio HTML.
Las posibilidades ahora que Angular está configurado en su tema son realmente infinitas, y al revisar el repositorio suministrado, tendrás un punto de partida rápido para la creación de las aplicaciones con Angular y Bootstrap, manos a la obra creemos una aplicacion single-page de WordPress.
¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!



