Advertisement
  1. Code
  2. iOS

Criando um Aplicativo Mobile Usando WordPress, Ionic e AngularJS

Scroll to top
Read Time: 15 min

Portuguese (Português) translation by João Fagner (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Introdução

Neste tutorial, vou explicar para você passo a passo como criar uma aplicação mobile moderna, híbrido para (iOS e Android) de seu site WordPress usando as mais recentes tecnologias. Estaremos usando Ionic Framework, ECMAScript 6npmwebpack, e Apache Cordova.

No final deste tutorial, você receberá a seguinte aplicação. Tem apenas três módulos, um módulo Home que exibe seus posts mais recentes, um módulo de Post que exibe um post específico e um módulo de Menu que exibe o menu.

ModulesModulesModules

1. Ferramentas

Ionic Framework

O maravilhoso, SDK open source front-end usado para desenvover íncriveis apps mobile com tecnologia web.

O ecossistema do Ionic Framework é grande, incluindo Ionic CLI (ferramenta de linha de comando), Ionic Push (notificações de push) e Ionic Platform (serviços de back-end). Atualmente é um dos principais projetos open-source no GitHub com mais de 19.000 estrelas e mais de 600.000 apps criados.

Ionic cobre todas as necessidades do seu aplicativo. No entanto, para este tutorial eu me focarei sobre Ionic Framework (ou Ionic SDK), que é um conjunto de diretivas do AngularJS (Componentes Web) e serviços.

ECMAScript 6 (ES6)

ECMAScript 2015 (6ª edição) é a versão atual do ECMAScript Padrão de Especificação de Linguagem (Language Specification standard). ES6 foi oficialmente aprovado e publicado como um padrão em 17 de junho de 2015, pela Assembleia Geral da ECMA.

ECMAScript 6 dá acesso a muitos recursos novos, muitos dos quais são inspirados por CoffeeScript, incluindo como funções de seta (arrow), geradores, classes e let escope. Mesmo sendo recente a aprovação ES6, você já pode usá-lo usando um compilador JavaScript, como Babel.

Node Gerenciador de Pacotes (npm)

Gerenciador de Pacotes Node é o gerenciador de pacotes mais popular do mundo. O número de pacotes está crescendo mais rápido do que Ruby, Python e Combinações de Java. npm é executado em Node.js.

Por Que não Bower?

Optamos por npm, porque usando Bower e npm no mesmo projeto vira algo problemático e o suporte de CommonJS com Bower não é simples. CommonJS define um formato de módulo para resolver escopo do JavaScript fora do navegador e npm suporta isto. Os módulos do CommonJS requerem o uso de ES5 ou ES6.

1
// ES5

2
var angular = require('angular');
1
// ES6

2
import angular from "angular";

webpack

Na minha opinião, webpack foi uma virada de jogo na indústria, solução para Grunt ou Gulp scripts que você precisa manter. webpack permite você solicitar qualquer tipo de arquivo (.js, .coffee, .css, .scss, .png, .jpg, .svg, etc.) e passá-los através de loaders (carregadores) para gerar assets estáticos que estarão disponíveis para seu aplicativo.

A diferença com o Grunt e Gulp é que a maioria de suas necessidades (minificação (minification) e compilação) pode ser coberta apenas adicionando algumas configurações, não há nenhuma necessidade de criar scripts. Por exemplo, requisitando um arquivo Sass, compilando, auto prefixing e injetando o resultante no CSS minificado (minified) em seu aplicativo será tão simples como isto:

1
{
2
    test: /\.scss$/,
3
    loader: "style!css!autoprefixer!sass"
4
}

Não acho que eu preciso mostrar-lhe o equivalente usando Gulp ou Grunt. Acho que você me entendeu.

2. Pré-requisitos

Este tutorial pressupõe que você tenha:

  • um conhecimento básico de AngularJS e Ionic
  • um site WordPress pronto para ser consultado (uma instalação local seria bom)
  • uma máquina com Node.js, npm, Bower (que vamos precisar para algumas dependências)
  • Git instalado com acesso de gravação sem sudo na pasta do projeto

3. Instalação

Antes de começar, você precisará instalar duas coisas:

  • um plugin WordPress que transforma seu blog em uma RESTFUL API
  • o próprio aplicativo

RESTFUL API

Para buscar os posts para sua instalação do WordPress, você precisará instalar o plugin WP REST API. Certifique-se de que você instale a versão 1.2. x a versão 2.x ainda está a caminho.

  1. Em WordPress, vá em  Plugins  > Adicionar novo.
  2. Pesquise por WP REST API (WP API).
  3. Clique em Instalar Agora para instalar o plugin.
  4. Se a instalação for bem-sucedida, clique em Ativar o Plugin para ativá-lo.

Se a instalação foi bem-sucedida, abra um navegador e digite http://example.com/wp-json. Isso deve lhe dar uma resposta semelhante a mostrada abaixo.

1
{
2
    "name": "Lorem Ipsum blog",
3
    "description": "Just another WordPress site",
4
    "URL": "http://yourDomainName.com/wp-json",
5
    "routes": {},
6
    "authentication": {},
7
    "meta": {}
8
}

Aplicação

Para instalar o aplicativo, clone o repositório, usando os seguintes comandos.

1
# Clone the repository and give it a name (here myTutorial)

2
$ git clone https://github.com/tutsplus/Hybrid-WordPressIonicAngularJS.git myTutorial
3
# Open the project

4
$ cd myTutorial

Em seguida, crie um arquivo de configuração e instale as dependências.

1
# Copy the default config to your personal config

2
$ cp config/default.config.json config/config.json
3
# Install dependencies

4
$ npm install

Para garantir que o aplicativo e a REST API trabalham juntos, abra  config/config.json. Este é o seu arquivo de configuração pessoal, que é ignorado pelo Git. Altere a URL base (base URL) da API para a da sua instalação do WordPress.

1
{
2
    "api": {
3
        "baseUrl": "http://yourDomainName.com/wp-json"
4
    }
5
}

Execute npm run devserver e abra http://localhost:8080//webpack-dev-servidor/ em um navegador. Se tudo funcionar como esperado, você deve estar na frente de um aplicativo em execução que exibe seus posts do WordPress. Eu criei um aplicativo de demonstração para lhe dar uma idéia do que esperar.

Agora que você pode ver o resultado do que iremos fazer, deixe-me passar os detalhes. Observe que os exemplos de código a seguir são simplificados. Você pode encontrar o código-fonte no GitHub.

4. Dependências

O comando npm install instalá várias bibliotecas. Algumas delas são dependências diretas, enquanto o resto são dependências de desenvolvimento.

Dependências Diretas

As dependências diretas são dependências que seu aplicativo precisa para funcionar corretamente quando construído.

1
"dependencies": {
2
    "ionic-sdk": "^1.0.0",
3
    "wp-api-angularjs": "^1.0.0"
4
}

Observe que o aplicativo não depende diretamente AngularJS, porque ionic-sdk já inclui o angular.js, angular-animate.js, angular-sanitize.js, e angular-ui-router.js.

wp-api-angularjs (cliente WordPress WP API para AngularJS) é um conjunto de serviços de AngularJS que permitem a comunicação com o plugin API REST que você instalou anteriormente. Você pode ver a lista completa das dependências no GitHub.

Dependências de Desenvolvimento

Dependências do desenvolvimento são principalmente webpack e loaders (carregadores). Loaders (Carregadores) são funções que leva a fonte de um arquivo de recurso, faz-se algumas alterações e retornam a nova fonte. Precisamos de loaders (carregadores) que lidam com .scss, .js (ES6), .html, e .json. Você pode ver uma lista completa das dependências de desenvolvimento no GitHub.

5. Arquitetura da Aplicação

Venho desenvolvendo aplicações com AngularJS por um longo tempo e depois de experimentar muito, me dediquei a seguinte arquitetura:

  • um arquivo que pode ser editado ao vivo sob a pasta src/ ou /lib
  • cada módulo AngularJS precisa de uma pasta apropriada
  • cada arquivo de *.module.js deve definir um namespace exclusivo (deve ser o único lugar onde aparece o namespace)
  • cada arquivo de módulo *.module.js deve declarar todas as suas dependências (mesmo se as dependências já forem injetadas no app)
  • cada arquivo de *.module.js deve declarar todas suas configurações (configs), controladores (controllers), serviços (services), filtros (filters), etc.
  • cada config (configuração), controller (controlador), service (serviço), filter (filtro), etc. deve exportar uma função (CommonJS)
  • se um módulo precisa de um estilo específico, o arquivo .scss deve estar dentro do módulo

Estas recomendações são importantíssimas elas asseguram que você tenha baixo acoplamento de módulos que podem ser compartilhados por vários aplicativos sem problemas.

A estrutura de pastas do aplicativo se parece com:

1
lib/
2
├── menu/
3
│   └── menu.module.js
4
│   └── menu.html
5
├── home/
6
│   └── home.module.js
7
│   └── home.config.js
8
│   └── home.controller.js
9
│   └── home.html
10
├── post/
11
│   └── post.module.js
12
│   └── post.config.js
13
│   └── post.controller.js
14
│   └── post.html
15
├── scss/
16
│   └── _variables.scss
17
│   └── bootstrap.scss
18
├── index.js
19
├── index.html

Ponto de Entrada

Quando é necessário usar o webpack como ponto de entrada. Nosso ponto de entrada é lib/index.js. Contém dependências básicas do nosso aplicativo (como ionic.bundle que contém AngularJS), nossos módulos home-made (feitos em casa) é adicionado ao ponto de entrada do Sass.

1
// Ionic, Angular & WP-API client

2
import 'ionic-sdk/release/js/ionic.bundle';
3
import 'wp-api-angularjs/dist/wp-api-angularjs.bundle';
4
5
// Our modules

6
import modHome from './home/home.module.js';
7
import modPost from './post/post.module.js';
8
import modMenu from './menu/menu.module.js';
9
10
// Style entry point

11
import './scss/bootstrap';

Agora que já importamos nossas dependências podemos criar o nosso módulo de aplicativo. Vamos chamar o nosso app de prototype. Tem o ionicwp-api-angularjs e nossos módulos home-made como dependências.

1
// Create our prototype module

2
let mod = angular.module('prototype', [
3
    'ionic',
4
    'wp-api-angularjs',
5
    modHome,
6
    modMenu,
7
    modPost
8
]);

Uma vez que o módulo é criado, nós podemos exportá-lo como um módulo padrão do CommonJS.

1
export default mod = mod.name;

Este é um grande exemplo de como um módulo de AngularJS deve parecer.

Routing (Roteamento de)

Routing architectureRouting architectureRouting architecture

Nosso aplicativo tem um menu lateral <ion-side-menu ui-view="menu"> no qual o módulo de Menu será processado. Também tem uma seção de conteúdo <ion-nav-view name= "content"> em que os módulos Home e Post aparecerá.

A directiva ui-view da interface do usuário é parte do UI-router  que usa Ionic. Está dizendo que $state (UI-router service) é onde colocamos os templates (modelos). Da mesma forma, a Diretiva de name (nome) anexada a <ion-nav-view> é uma diretiva do Ionic personalizada que está usando a interface do ui-view por baixo. Você pode considerar ambas as directivas idênticas.

Aqui é uma versão simplificada do estado de root, o estado que compartilha todos os módulos:

1
export default function($stateProvider) {
2
    'ngInject';
3
    return $stateProvider.state('root', {
4
        abstract: true,
5
        views: {
6
            '@': {
7
                template: `<ion-side-menus>

8
                    <ion-side-menu-content>

9
                        <ion-nav-bar class="bar-positive"></ion-nav-bar>

10
                        <ion-nav-view name="content"></ion-nav-view>

11
                    </ion-side-menu-content>

12
                    <ion-side-menu side="left" ui-view="menu"></ion-side-menu>

13
                </ion-side-menus>`
14
            }
15
        }
16
    });
17
}

Para obter mais informações sobre nomes das views, consulte a documentação no GitHub.

Módulo Menu

Menu ModuleMenu ModuleMenu Module
1
lib/
2
├── menu/
3
│   └── menu.module.js
4
│   └── menu.html

O módulo de Menu é muito simples. Sua finalidade é adicionar um menu dentro <ion-side-menu>. Sem este módulo o menu lateral ficaria em branco. O módulo de menu declara apenas um arquivo de configuração, tem ionic e ui.router como dependências.

1
import modConfig from './menu.config';
2
3
let mod = angular.module('prototype.menu', [
4
    'ionic',
5
    'ui.router'
6
]);
7
8
mod.config(modConfig);
9
10
export default mod = mod.name;

A parte mais interessante é a configuração. Nós não queremos criar um state (estado) para o módulo de Menu como ele está disponível em todos os lugares. Em vez disso, nós decoramos o state (estado) root com o conteúdo do menu. Com o ui-view="menu" sendo definida no state (estado) root, precisamos usar menu@root para nós referirmos a ele.

1
export default function($stateProvider) {
2
    'ngInject';
3
    $stateProvider.decorator('views', (state, parent) => {
4
        let views = parent(state);
5
        if (state.name === 'root') {
6
            views['menu@root'] = {
7
                template: require("./menu.html")
8
            };
9
        }
10
        return views;
11
    });
12
}

Módulo Home

Home ModuleHome ModuleHome Module
1
lib/
2
├── home/
3
│   └── home.module.js
4
│   └── home.config.js
5
│   └── home.controller.js
6
│   └── home.html

Home.Module.js

O módulo de Home exibe os últimos posts do seu site WordPress. Tem um arquivo de config (configuração), um controller (controlador), e depende das seguintes bibliotecas:

  • ionic
  • ui.router
  • wp-api-angularjs
1
import modConfig from './home.config';
2
import modController from './home.controller';
3
4
let mod = angular.module('prototype.home', [
5
    'ionic',
6
    'ui.router',
7
    'wp-api-angularjs'
8
]);
9
10
mod.config(modConfig);
11
mod.controller('HomeController', modController);
12
13
export default mod = mod.name

home.config.js

O config (configuração) adiciona um novo state (estado), root.home com /homeURL que tem um template (modelo) e um controller (Controlador) (ambos dentro do módulo).

1
export default function($stateProvider) {
2
    'ngInject';
3
    $stateProvider.state('root.home', {
4
        url: "/home",
5
        views: {
6
            'content@root': {
7
                template: require("./home.html"),
8
                controller: "HomeController as homeCtrl"
9
            }
10
        }
11
    });
12
}

home.controller.js

Esta é uma versão simplificada da lógica do Home controller (controlador) Ele contém duas funções:

  • loadMore: Essa função preenche vm.posts. Ele usa o serviço de $wpApiPosts, que faz parte da biblioteca de wp-api-angularjs.
  • refresh: Esta função remove posts e chama loadMore novamente.
1
export default function($scope, $log, $q, $wpApiPosts) {
2
    'ngInject';
3
4
    var vm = this;
5
    vm.posts = [];
6
    vm.loadMore = loadMore;
7
    vm.refresh = refresh;
8
9
    function refresh() {
10
        vm.posts = null;
11
        loadMore().finally(() => $scope.$broadcast('scroll.refreshComplete'));
12
    }
13
14
    function loadMore() {
15
        return $wpApiPosts.$getList().then((response) => {
16
            vm.posts = (vm.posts) ? vm.posts.concat(response.data) : response.data;
17
            $scope.$broadcast('scroll.infiniteScrollComplete');
18
        });
19
    }
20
}

home.html

O template tem uma diretiva de ion-refresher que permite aos usuários recarregar a página puxando (pulling) a página para baixo. Tem também uma ion-infinite-scroll diretiva que chama a função loadMore quando for atingido. Posts são exibidos usando a diretiva de ng-repeat.

Dica: Use o track by expressão para melhorar desempenho. Ele minimiza a manipulação do DOM quando um post é atualizado.

1
<ion-view>
2
    <ion-nav-title>Home</ion-nav-title>
3
    <ion-content>
4
        <ion-refresher pulling-text="Pull to refresh" on-refresh="homeCtrl.refresh()"></ion-refresher>
5
        <div class="list card" ng-repeat="post in homeCtrl.posts track by post.ID">
6
            <!-- THE POST DETAILS -->
7
        </div>
8
        <ion-infinite-scroll immediate-check="true" on-infinite="homeCtrl.loadMore()"></ion-infinite-scroll>
9
    </ion-content>
10
</ion-view>

Módulo de Post (Post Module) 

1
lib/
2
├── post/
3
│   └── post.module.js
4
│   └── post.config.js
5
│   └── post.controller.js
6
│   └── post.html

O módulo Post exibe apenas um post. Tem um arquivo de config (configuração), um controlador (controller), e depende da mesma biblioteca que o módulo Home.

post.module.js

1
import modConfig from './post.config';
2
import modController from './post.controller';
3
4
let mod = angular.module('prototype.post', [
5
    'ionic',
6
    'ui.router',
7
    'wp-api-angularjs'
8
]);
9
10
mod.config(modConfig);
11
mod.controller('PostController', modController);
12
13
export default mod = mod.name

Semelhante ao módulo Home, a configuração adiciona um novo estado, root.post, com o /post/:id URL de identificação. Ele também registra a view (visão) e um controller (controlador).

post.config.js

1
export default function($stateProvider) {
2
    'ngInject';
3
    $stateProvider.state('root.post', {
4
        url: "/post/:id",
5
        views: {
6
            'content@root': {
7
                template: require("./post.html"),
8
                controller: "PostController as postCtrl"
9
            }
10
        }
11
    });
12
}

post.controller.js

O controller recupera o post especificado na url /post/:id identificando através do serviço $stateParams (UI router service).

1
export default function ($scope, $log, $wpApiPosts, $stateParams) {
2
    'ngInject';
3
    var vm = this;
4
    vm.post = null;
5
    $scope.$on('$ionicView.loaded', init);
6
7
    function init() {
8
        $wpApiPosts.$get($stateParams.id).then((response) => {
9
            vm.post = response.data;
10
        });
11
    }
12
}

post.html

O template tem uma diretiva ion-spinner que exibe um loader (carregador), enquanto os dados estão sendo buscados da API do resto do WordPress. Quando o post é carregado, usamos um Ionic card para processar o avatar do autor (author avatar), o título do post (the post title) e o conteúdo do post (post content).

Dica: Use a expressão bindOnce, expressão, :: , (introduzido em Angular 1.3 ) para evitar visualizar dados que não vão mudar ao longo do tempo.

1
<ion-view>
2
    <ion-nav-title>{{postCtrl.post.title}}</ion-nav-title>

3
    <ion-content>
4
        <ion-spinner ng-if="!postCtrl.post"></ion-spinner>

5
        <div class="list card" ng-if="postCtrl.post">
6
            <div class="item item-avatar">
7
                <img ng-src="{{::postCtrl.post.author.avatar}}">
8
                <h2>{{::postCtrl.post.author.name}}</h2>

9
                <p>{{::postCtrl.post.date | date:'medium'}}</p>

10
            </div>

11
            <div class="item item-body">
12
                <img class="full-image" ng-src="{{::postCtrl.post.featured_image.attachment_meta.sizes.medium.url}}">
13
                <h2>{{::postCtrl.post.title}}</h2>

14
                <p ng-bind-html="::postCtrl.post.content"></p>

15
            </div>

16
        </div>

17
    </ion-content>

18
</ion-view>

Estilo (Sass)

1
lib/
2
├── scss/
3
│   └── _variables.scss
4
│   └── bootstrap.scss

O arquivo de bootstrap.scss que nós importamos em nosso ponto de entrada é tão simples como isto:

1
@import "./variables";
2
@import "~ionic-sdk/scss/ionic";

Primeiro, nós importamos nossas variáveis. Então, nós importamos os estilos do Ionic. Importando nossas variáveis antes Ionic nos permite sobrescrever qualquer variável Sass que Ionic tenha declarado.

Por exemplo, se você quiser a cor positive que seja red (vermelho) em vez de blue (azul), você pode substituí-lo assim:

1
$positive: red !default;

6. Android e iOS

Instalação

Execute os seguintes comandos dentro da pasta do projeto e escolha a plataforma para qual você que construir.

1
$ cp config.dist.xml config.xml
2
$ npm run installCordova
3
4
Which platforms do you want to build? (android ios):

Além de instalar plataformas dentro da pasta /platforms, o script irá instalar um plugin. Para a demonstração, precisamos do plugin do cordova-plugin-whitelist É necessário permitir que o aplicativo consulte a REST API WordPress que criamos anteriormente.

Se você abrir o config.xml, verá que permitimos o acesso para qualquer tipo de origem (<access origin="*">). Claro, isso é apenas para fins de demonstração. Se você implanta seu aplicativo de produção certifique-se de de restringir o acesso como este:

1
<access origin="http://example.com" />

Andróide

Pré-requisitos

  • SDK do Android
  • Ant

Executando o comando npm run runAndroid é um atalho para rm -rf www/* && webpack && cordova run android. Isto remove tudo dentro da pasta www, despeja uma versão non-minified (não-minificada) do app e executa o comando android. Se estiver conectado a um dispositivo Android (execute o adb devices tenha certeza), o comando irá carregar o aplicativo no dispositivo, caso contrário ele irá usar o emulador Android.

1
# Run Android

2
$ npm run runAndroid

iOS

Pré-requisitos

  • OS X
  • Xcode

Se você não tiver um dispositivo da Apple, você deve instalar o iOS Simulator. É muito bom e melhor que o emulador Android .

1
$ sudo npm install -g ios-sim

Executando npm run runIosEmulator é um atalho para o rm -rf www/* && webpack && cordova run ios. O comando npm, npm run runIosDevice é um atalho para o rm -rf www/* && webpack && cordova run ios --device.

1
# Run iOS

2
$ npm run runIosEmulator
3
$ npm run runIosDevice

Conclusão

Com este tutorial, tentei mostrar a você como é fácil criar uma aplicação mobile híbrida para o seu site WordPress. Você deve ser capaz agora de:

  • criar módulos flexíveis nesse aspecto com as especificações CommonJS
  • Importar módulos CommonJS com ECMAScript 6
  • usar o WordPress REST API client side (com wp-api-angularjs)
  • Potencializado com Ionic Framework para criar uma interface de usuário agradavel
  • Usar o webpack para agregar seu aplicativo
  • Use Cordova para executar o aplicativo no iOS e Android

Se você quiser ir mais longe, então dê uma olhada um projeto que eu criei há alguns meses, WordPress Hybrid Client (Cliente de Híbrido).

WordPress Hybrid Client (Cliente de Híbrido)

WordPress Hybrid Client (WPHC) é um projeto open-source disponível no GitHub que ajuda você a criar versões de seu site WordPress para aplicativos iOS e Android gratuitamente. WPHC baseia-se na mesma pilha tecnologica que usamos neste tutorial.

WPHC inclui os seguintes recursos:

  • notificações push
  • bookmarks (favoritos) (modo offline)
  • Suporte do Google Analytics
  • atualizações automáticas de conteúdo
  • botões de redes sociais
  • acessibilidade (tamanho de fonte do post)
  • vários idiomas (Inglês, francês e chinês)
  • rolagem infinita
  • realce de sintaxe para blogs de tecnologia
  • cache de imagem
  • avaliação de App

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.