基于 WordPress REST API 開發“微信小程序”

基于 WordPress REST API 開發“微信小程序”

幾周前,Jeff 花了兩天將自己的 WordPress 網站做了個微信小程序版本(詳細見該文)。這篇文章主要記錄自己在開發第一版的過程,順便為有興趣的你剖析如何將一個WordPress 網站借助 REST API 開發微信小程序版。本文目標受眾為了解WordPress 且有初級前端知識的同學。

原理篇

WordPress 與 REST API

WordPress 在4.4 版本后推出了 REST API, REST API 簡單來說就是一種通過 HTTP 請求來獲取、更新、刪除數據的一種連接客戶端與服務端的交互方式。我們訪問平常的普通 WordPress 網頁,在沒有開啟靜態緩存的情況下,大概是走“從數據庫拉取數據—> 服務端 PHP 進程拼成 HTML 直接輸出 —> 用戶瀏覽器界面”的過程, REST API 也是類似步驟,但后面兩步稍微不同:輸出的是 JSON 格式的數據且一般是給客戶端使用。有了REST API,一個網站制作各種網站版本(安卓版、iOS 版、以及接下來說的小程序版)而共享一個數據庫成為了可能。

基于 WordPress REST API 開發“微信小程序”

(原圖來自 wisdmlabs,稍作修改)

以本站為例,可通過瀏覽器直接訪問REST API 的其中一種URL:https://devework.com/wp-json/wp/v2/posts?per_page=5&page=1 (如果你現在直接訪問是403 報錯,那是我為了安全而設置的攔截,請自行替換為自己網站的域名),你可能會看到如下圖左側的界面;如果你使用Chrome 瀏覽器且安裝JSONView 插件則為下圖右側的界面。

基于 WordPress REST API 開發“微信小程序”

wordpress 中的rest api

且讓Jeff 將上面的URL 解釋下,/wp-json/wp/v2/ 這個是WordPress 定義的REST API 的“路由”(router)與版本號等的組合,合在一起稱作“命名空間”(namespace),posts 在WordPress中稱為“終點” (endpoint),per_page 與page 則是相關參數。 關于REST API 的名詞解釋可以參考阮老師的文章。上面的URL 即表示輸出第1頁最新5篇文章的數據(5篇為1頁)。這個URL 接下來將要用到。

微信小程序

微信小程序就不多介紹了,雖然剛開始不溫不火,但接下來必然是在國內互聯網占據一定的地位。本文在這里也不多談什么小程序前景如何這些空大話,既然你看到這兒必然是對小程序有興趣且在某種程度上有一定的肯定。

WordPress + 小程序

微信小程序通過 REST API 獲取到 WordPress 網站上的數據,然后通過一定的方式在小程序端進行數據處理后通過前端代碼渲染,然后就是你在微信客戶端上看到的界面。

WordPress 的REST API 現在開發得已經很完善了,什么文章數據、頁面數據、用戶數據等都不在話下,把 WordPress 作為小程序的后端實在是省了不少人力,至少對我們這些前端狗來說不用寫苦逼的后端代碼。

開發篇

上一章節大致介紹了原理后,接下來就以本站開發的“DeveWork極客”小程序第一版v1.0 為例,介紹三個頁面(首頁、內容頁、閱讀記錄頁)大體上是如何做出來的。可以掃描下面的小程序碼體驗一下,注意看文章的此時你掃描進入的版本可能不是不是第一版了。要看懂本章節的內容,需要你對小程序開發有一定的了解(不要求看完文檔,但至少也跑一下官方的例子吧)。另外本章節也不會涉及如何寫CSS(WXSS)的部分,默認讀者有這方面的基礎。

準備工作

準備工作就不細說,大體上包括如下操作:一是微信公眾平臺管理后臺上注冊小程序賬號,配置域名等信息;二是服務端確保配置好HTTPS、“合法域名”這塊是已經備案的域名。

另外在開始開發之前,我在服務端對WordPress REST API 進行了一些定制化的輸出

項目結構

結合微信官方quick start 的例子與個人需求,將項目結構如下分好:


.
├── app.js
├── app.json
├── app.wxss 
├── config.js // 配置文件
├── image // 圖片目錄
├── pages // 頁面目錄
├── utils // 實用untils 類
└── wxParse // 第三方庫wxParse

基于 WordPress REST API 開發“微信小程序”

小程序首頁(文章列表頁面)

首頁即文章列表頁面, 即展示最新的5篇文章,然后通過下拉流式加載更多文章(有點無限加載的意味)。使用到WordPress 的REST API 就是 your-site.com/wp-json/wp/v2/posts?per_page={num}&page={num}。

index.js 文件里面核心是通過wx.request 接口訪問上面的API URL 獲取到文章數據并setData 供后續數據渲染:


// https://devework.com/wordpress-rest-api-weixin-weapp.html
wx.request({
    url: url,
    success: function (response) {
        self.setData({
            posts: self.data.posts.concat(response.data.map(function (item) {
            	 ...
            	 // 數據過濾/格式化等
            	 ...
                return item;
            }))
        });
    }
  });
}

上面的代碼我是抽出在一個函數中,方便后續重復調用。設置的數據通過index.wxml 循環輸出,當前在此之前因為要做滾動加載,所以采用了小程序的scroll-view組件(官方文檔)。


<scroll-view scroll-y="true" bindscrolltolower="pullDownRefresh">
     <block wx:for-items="{{posts}}" wx:key="{{item.id}}">
     	<view class="entry" index="{{index}}" id="{{item.id}}" catchtap="redictSingle">
          <!--文章數據的展示,細節代碼略過-->
	     </view>
    </block>
</scroll-view>

上面的WXML 代碼中綁定了兩個事件函數:一是下拉事件pullDownRefresh(),一個是點擊事件redictSingle(),即點擊后跳轉到文章詳情頁。


// https://devework.com/wordpress-rest-api-weixin-weapp.html
// 下拉刷新
pullDownRefresh: function (event) {
    var self = this;
    self.setData({
        page: self.data.page + 1 //頁面+1
    });
    console.log('current page:' + self.data.page);
    this.fetchData({ page: self.data.page });
},
 
// 路由導航到文章內頁
redictSingle: function (event) {
    console.log('redictSingle');
    var id = event.currentTarget.id; // 這里的id 其實是WordPress 中的文章id,需要傳遞到single 頁面
    var url = '../single/single?id=' + id;
    wx.navigateTo({
        url: url
    })
}

文章內頁(文章詳情頁面)

文章頁使用到的REST API URL是your-site.com/wp-json/wp/v2/posts/{id}。也是類似,通過wx.request 接口訪問URL 然后渲染數據到WXML 頁面上。代碼與上面的類似就不重復了。

這里其實涉及到個如何將富文本轉為微信小程序可識別的WXML 的問題。因為獲取的JSON 數據文章正文部分是一段HTML 代碼,如果直接輸出是會報錯的,需要將這段HTML 代碼(俗稱富文本)轉化為微信小程序WXML 語言。Jeff 使用的是WxParse 這個第三方庫,不過這個庫目前來說依然不是很完善,接上去之后發現有不少 bug,還好憑借自己的技術給打補丁般一個個修復了。

使用上,按照WxParse 的文檔,在獲取到文章數據后,經過html to wxml 的步驟后賦值到page data:


// https://devework.com/wordpress-rest-api-weixin-weapp.html
// html to wxml
let article = res.data.content.rendered;
WxParse.wxParse('article', 'html', article, self, 5);
 
self.setData({
    wxParseData: article.nodes
});

wxml 上,import 導入wxParse.wxml 并調用:


// https://devework.com/wordpress-rest-api-weixin-weapp.html
// html to wxml
<import src="../../wxParse/wxParse.wxml"/>
<view class="entry__cotent ">
    <template is="wxParse" data="{{wxParseData:article.nodes}}"/>
</view>

以上就是接入WxParse 的過程粗略介紹。

7月29日更新:小程序現在出了富文本組件(rech-text),個人評價么,暫時還比不上 wxParse。當前支持的標簽有限(如pre標簽不支持)且不支持綁定事件,暫時還是先用著wxParse。

閱讀記錄頁面

基于 WordPress REST API 開發“微信小程序”

閱讀記錄頁面是用來展示用戶瀏覽歷史,直接照著官方的Hello World 例子就做起來了。這個頁面用到的主要如下兩種接口:LocalStorage 相關接口、用戶授權相關接口(wx.login,wx.getUserInfo等)。

從用戶體驗上考慮,不應該一開始就向用戶申請授權,而是有需要的頁面才申請;同時也應該做好用戶不允許授權的優雅處理。在這里因為小程序的坑以及個人關系第一版處理得不是很完美,代碼就不展示了。

6月14日更新:處理授權相關的內容參考《提升用戶體驗,微信小程序“授權失敗”場景的優雅處理》

記錄的文章閱讀歷史數據是以LocalStorage 的形式保存在客戶端而非云端,一句“閱讀記錄僅保存在本設備”的提示是有必要的。同時基于容量上的考慮將最多數目限制為20條。


// https://devework.com/wordpress-rest-api-weixin-weapp.html
// 調用API從本地緩存中獲取閱讀記錄并記錄
var logs = wx.getStorageSync('readLogs') || [];
// 過濾重復值
if (logs.length > 0) {
    logs = logs.filter(function (log) {
        return log[0] !== id;
    });
}
// 如果超過指定數量
if (logs.length > 19) {
    logs.pop();//去除最后一個
} 
logs.unshift([id, response.data.title.rendered]);
wx.setStorageSync('readLogs', logs);

上面的代碼其實是放在single.js里面的,因為需要將文章id 與標題保存在LocalStorage 上,只有single.js才同時獲取這兩種數據。

基于 WordPress REST API 開發“微信小程序”

最后還需要在log.js 的onShow生命周期綁定一個更新數據的函數:


// https://devework.com/wordpress-rest-api-weixin-weapp.html
updateData: function(cb){
        var that = this;
        // readlog 
        this.setData({
            readLogs: (wx.getStorageSync('readLogs') || []).map(function (log) {
                return log;
            })
        })
    },

踩坑篇

這個章節主要記錄在開發過程中的一些坑以及解決方案。

TabBar 的圖片問題

小程序官方宣稱支持SVG 圖片,但在tabBar 里面的圖片并不支持SVG 圖片。官方推薦采用81x81 尺寸的png 圖片,但這個依然有點坑。建議在設計icon 的時候稍微留點透明的padding 占位,不然會導致圖標在真機上會放得很大。

圖片防盜鏈的referer 設置

如果你托管圖片的服務器有防盜鏈處理,那么得將servicewechat.com放入白名單中,并不是想當然的qq.com。

Image 的絕對路徑必須以https 開頭

image 的src 絕對路徑,在web 開發中是允許類似//example.com/pic.png的以//開頭的存在,這種圖片路徑在微信web 開發者工具也能正常顯示,但在真機上就不能正常加載了,必須是https 開頭的絕對路徑。

服務端數據側不好處理的話可以通過下面的util 處理:


// https://devework.com/wordpress-rest-api-weixin-weapp.html
// 補全URL 中缺失的 HTTPS
function addhttps(url) {
  if (!/^(f|ht)tps?:\/\//i.test(url)) {
    url = "https:" + url;
  }
  return url;
}

開發者工具的小程序UA 與實際UA 不同

開發工具中模擬的小程序UA 是類似:

... Chrome/53.0.2785.143 Safari/537.36 appservice webview/100000

而通過Nginx 的log 可以查看到實際的UA 是類似(其實就是微信的UA):

... Mobile/14E304 MicroMessenger/6.6.0 NetType/WIFI Language/zh_CN

某些情況下需要注意這些不同。

默認的Flex 布局

如果你是在官方例子的代碼基礎上開發你的小程序的,建議先刪掉app.wxss 的flex 布局相關代碼,會降低你遇到奇葩樣式問題的概率。

wxParse 的坑1:code 字符被錯誤替換

小程序使用到的富文本轉化是用wxParse 這個第三方庫,用的時候發現有不少坑(但目前是這個庫最為實用了)。其中一個就是全局的code 字符都被替換為wx-codexxx 類似的坑,作者本意應該是對code 標簽進行這個替換,但可能一不小心寫錯了。解決方案是暫時刪掉那段代碼。

wxParse 的坑2:image的src 多解析出一個逗號

看圖說話:

基于 WordPress REST API 開發“微信小程序”

上圖也很好解釋了上面的referer 坑與圖片路徑https 開頭的坑。解決方案只能先改動源碼(html2json.js 約L130)Fix 下:


// https://devework.com/wordpress-rest-api-weixin-weapp.html
// Fix: img 標簽數組含有空字符的問題
if (imgUrl[0] == ''){
  imgUrl.splice(0, 1);
}

總結篇

至此詳略得當地介紹了開發這個WordPress 版小程序的過程,接下來的工作自然是提交到官方并耐心等待審核結果的通知。整個開發過程其實并不太有難度,如果之前有使用過Angular、Vue 這類MVVM 框架,整個開發過程基本上只是看官方文檔的問題。

本文出處:DeveWork 內容有所刪減

相關推薦

微信掃一掃

微信掃一掃

微信掃一掃,分享到朋友圈

基于 WordPress REST API 開發“微信小程序”
返回頂部

顯示

忘記密碼?

顯示

顯示

獲取驗證碼

Close
七星彩走势图500