返回博客首页
← 所有文章

在原生移动应用中使用 WordPress 内容

2018年2月15日 — 作者:Rob Lauer

WordPress 是迄今为止最流行的内容管理系统 (CMS)。WordPress 占据了 60% 的 CMS 市场份额,此外,几乎 30% 的所有网站运行在 WordPress 上。这意味着大量的网站内容渴望以新的方式,在新的设备上被使用。在某些情况下,在原生移动应用中利用这些内容非常有意义。此时,NativeScript 就派上用场了。

wordpress and nativescript

是的,WordPress 用于管理网页内容 (HTML),而 NativeScript 是一个用于构建跨平台原生移动应用的框架(绝对不是 HTML)。那么这两者有什么共同点呢?

我们不建议在移动应用中重新创建网站。这样做有违反苹果应用商店条款的风险,因为该应用不具有独特性或“应用特性”,更重要的是,如果只是简单地重新创建相同的网页体验,用户很可能避开你的应用。这是一个发挥创意的机会!👨‍🎨

API 万岁

就像任何一段伟大的关系一样,这一切都始于一个 RESTful API……

NativeScript + WordPress = 😍

WordPress 自带了RESTful API 端点用于 WordPress 数据类型,为网页开发者(以及移动和桌面开发者)提供了以新颖且令人兴奋的方式与存储内容交互的能力。当然,提供的端点与语言无关。任何可以消费 JSON 的框架都会愉快地消化 WordPress 提供的内容。鉴于 NativeScript 应用构建在 JavaScript 之上,使用简单的fetch调用来使用此类 API 是标准做法。

让我们构建一个应用

我想,如果你在这里,你可能有一个现有的 WordPress 网站,其中包含数周、数月甚至数年的内容。在原生、跨平台的移动应用中重新利用这些内容的潜力至少可以说是很有吸引力的。

我认为学习新事物最好的方法就是自己动手。所以让我们构建一个应用吧!

让我们构建一个简单的 NativeScript 应用,以利用 WordPress 内容类别、文章和文章内容,并在 iOS 和 Android 上运行,所有这些都来自同一个共享代码库。

虽然本文不会深入探讨 WordPress API,但可以肯定地说该 API 文档齐全

NativeScript Sidekick

相信我,每个优秀的 NativeScript 应用都始于NativeScript Sidekick提供的入门套件。

Sidekick 是一款适用于 Mac、Windows 和 Linux 的免费工具,它运行在 NativeScript CLI 之上,为你提供模板、插件管理、云构建和应用商店发布功能。

"Sidekick 周" 博客系列中了解 NativeScript Sidekick 提供的所有功能。

安装 Sidekick 后,打开它,创建一个新的应用,并选择空白模板

nativescript sidekick starter templates

我将坚持使用纯 JavaScript,但如果你更习惯于这些架构,欢迎使用 TypeScript 或 Angular。

在我们打开首选代码编辑器之前,让我们向应用中添加一些我们知道需要的页面。

点击新建页面按钮,并向我们的应用添加两个页面或视图。

nativescript sidekick add new page

这两个页面都可以是空白页面,你可以将第一个命名为category,第二个命名为post

代码

我们的脚手架应用具有三个基本视图

  • home-page.xml(随空白模板提供)
  • category-page.xml(你创建的)
  • post-page.xml(你创建的)

现在需要指出的是,如果你迷路了,可以在Github 上找到此应用的完整版本

我们的main-page视图只是一个按钮。因为谁不喜欢一个好的按钮呢?

wordpress button screen

要渲染该屏幕,我们的/home/home-page.xml文件只需要一些简单的布局代码和一个按钮

<Page xmlns="http://schemas.nativescript.org/tns.xsd"
    class="page bg"
    backgroundSpanUnderStatusBar="true">

    <Page.actionBar>
        <ActionBar title="WordPress + NativeScript = ❤️" class="action-bar">
        </ActionBar>
    </Page.actionBar>

    <StackLayout class="p-20">
        <Label text="WordPress Demo" class="h1 text-center m-t-30 heading"/>
        <Button text="Load Categories" tap="showCategories" class="btn btn-primary btn-active"/>
    </StackLayout>

</Page>

…以及其对应的home-page.js文件需要一些管道工作来连接按钮,以便将我们发送到下一个视图category-page

var frameModule = require('ui/frame');

exports.showCategories = function() {
  var navigationEntry = {
    moduleName: './category/category-page',
    animated: true
  };
  var topmost = frameModule.topmost();
  topmost.navigate(navigationEntry);
};

现在变得有趣了。打开/category/category-page.xml并用以下 NativeScript ListView(包括项目模板)替换现有代码,如下所示

<Page xmlns="http://schemas.nativescript.org/tns.xsd"
    class="page bg"
    loaded="pageLoaded">

    <Page.actionBar>
        <ActionBar title="WordPress Categories" icon="" class="action-bar">
            <NavigationButton text="Back" android.systemIcon="ic_menu_back" />
        </ActionBar>
    </Page.actionBar>

    <ListView id="listview" items="{{ items }}" class="list-group">
        <ListView.itemTemplate>
            <StackLayout class="list-group-item" id="{{ id }}" tap="showPost">
                <Label text="{{ name }}" class="wp-category" />
                    <Label text="{{ description }}" textWrap="true" class="wp-subtitle" />
                </StackLayout>
        </ListView.itemTemplate>
    </ListView>

</Page>

此视图的配套 JavaScript 文件category-page.js包含两个函数。pageLoaded不出所料,在页面加载时执行,而showPost将引导我们到下一个视图(post-page),并保留用户点击的类别的上下文

var frameModule = require('ui/frame');
var Observable = require('data/observable').Observable;
var ObservableArray = require('data/observable-array').ObservableArray;

var page;
var items = new ObservableArray([]);
var pageData = new Observable();

exports.pageLoaded = function(args) {
  page = args.object;
  page.bindingContext = pageData;

  fetch('https://demo.wp-api.org/wp-json/wp/v2/categories')
    .then(response => {
      return response.json();
    })
    .then(function(r) {
      pageData.set('items', r);
    });
};

exports.showPost = function(args) {
  var navigationEntry = {
    moduleName: './post/post-page',
    animated: true,
    context: { id: args.view.id }
  };

  var topmost = frameModule.topmost();
  topmost.navigate(navigationEntry);
};

这为我们提供了一个包含 WordPress 文章类别的简洁屏幕

wordpress categories

category-page.js中的关键代码是fetch APIfetch允许我们从远程端点请求数据并以 JSON 格式返回,使其易于在我们的应用中使用!

你还会很快注意到我们正在使用的 API 端点正在利用 WordPress 演示数据集。其中包含大量乱数文本。

如果我们查看返回的 JSON,我们会看到一个非常清晰的数据集

"id":2,
"count":3,
"description":"Neque quibusdam nihil sequi quia et inventore",
"link":"https:\/\/demo.wp-api.org\/category\/aut-architecto-nihil\/",
"name":"Aut architecto nihil",
"slug":"aut-architecto-nihil",
"taxonomy":"category",
"parent":0,
...

好的,让我们完成并用另一个ListView替换post/post-page.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd"
    class="page bg"
    navigatedTo="pageNavigatedTo">

    <Page.actionBar>
        <ActionBar title="WordPress Posts" icon="" class="action-bar">
            <NavigationButton text="Back" android.systemIcon="ic_menu_back" />
        </ActionBar>
    </Page.actionBar>

    <ListView id="listview" items="{{ items }}" class="list-group">
        <ListView.itemTemplate>
            <StackLayout class="list-group-item" link="{{ link }}" tap="loadWebSite">
                <Label text="{{ title.rendered }}" class="wp-subtitle" />
                </StackLayout>
        </ListView.itemTemplate>
    </ListView>

</Page>

…同样,我们的post-page.js代码位于后面,为视图提供支持,并且包含另外两个函数:pageNavigatedToloadWebSite,它们分别执行fetch请求以加载我们的文章,并启动一个NativeScript WebView,以便在应用内浏览器中显示文章内容的 HTML 输出。

var frameModule = require('ui/frame');
var pageModule = require('ui/page');
var webViewModule = require('ui/web-view');
var Observable = require('data/observable').Observable;
var ObservableArray = require('data/observable-array').ObservableArray;

var page;
var items = new ObservableArray([]);
var pageData = new Observable();

exports.pageNavigatedTo = function(args) {
  page = args.object;
  page.bindingContext = pageData;

  var id = page.navigationContext.id;

  fetch('https://demo.wp-api.org/wp-json/wp/v2/posts?categories=' + id)
    .then(response => {
      return response.json();
    })
    .then(function(r) {
      pageData.set('items', r);
    });
};

exports.loadWebSite = function(args) {
  var link = args.view.link;

  var factoryFunc = function() {
    var webView = new webViewModule.WebView();
    webView.src = link;
    var page = new pageModule.Page();
    page.content = webView;
    return page;
  };

  var topmost = frameModule.topmost();
  topmost.navigate(factoryFunc);
};

虽然我省略了一些细节以节省空间,但需要提醒的是,所有这些代码都可以在 Github 上找到

我们完成了!当然,如果你按原样运行应用,它可能看起来与这些屏幕截图不完全一样。除非你从Github获取完整的app.css/images/bg.png背景图像和/fonts中的字体文件,并将它们添加到你的应用中。

部署你的应用

回到 NativeScript Sidekick 中,转到运行菜单,然后选择在设备上运行。选择要运行应用的已连接设备,并使用我们的云服务器构建应用(或者如果你已设置了相应的 SDK,则可以在本地构建)。

部署应用时遇到任何问题?请查阅NativeScript Sidekick 文档

nativescript sidekick run on device

在网页和移动平台之间共享网站内容是一回事。那么,如何与移动设备共享实际的网站代码呢?虽然与 WordPress 无关,但如果你是一名 Angular 开发人员,并且对 NativeScript + Angular 网页/移动代码共享故事感兴趣,请务必查看我们在 YouTube 上的代码共享网络研讨会

总结

今天,我们了解了如何使用 WordPress REST API 使用现有的 WordPress 内容来为 NativeScript 提供真正的原生跨平台应用。通过使用一些 JavaScript 和 CSS,你可以重新利用多年的内容,并为用户提供新的、引人入胜的用户体验。快乐的 NativeScripting!😁