├── .gitignore
├── .travis.yml
├── CNAME
├── Gemfile
├── LICENSE
├── README.md
├── _config.yml
├── _layouts
└── default.html
├── _sass
├── jekyll-theme-cayman.scss
├── normalize.scss
├── rouge-github.scss
└── variables.scss
├── assets
└── css
│ └── style.scss
├── index.md
├── jekyll-theme-cayman.gemspec
└── script
├── bootstrap
├── cibuild
├── release
└── server
/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .sass-cache
3 | Gemfile.lock
4 | *.gem
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | cache: bundler
3 | sudo: false
4 | rvm: 2.2
5 |
6 | install: script/bootstrap
7 | script: script/cibuild
8 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | wechat.twindy.org
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### wechat-app-issues
2 |
3 | 早就知道小程序这个坑很深,一个多月的实践发现这个坑果然名不虚传...
4 |
5 | 不过,开发的小程序如期上线了,还是值得庆贺!!!呵呵,记录一下那些让自己停顿的点。
6 |
7 | #### 一、开发微信小程序遇到的坑
8 |
9 | - 1、 {{}} 不能执行方法,只能处理简单的运算如 “+ - * /”,比如遇到遍历list,每个item的金额需要格式化,只能在js里预先格式化好再setData一遍( ╯□╰ )
10 | - 2、只能通过,只能通过,只能通过setData()更新视图,坑..........
11 | - 3、我们规定页面路径只能是五层,请尽量避免多层级的交互方式。
12 | - 4、A页面-->B页面,B页面返回A,如何触发A的刷新,不增加页面层级。
13 | 暂时想到的方案:在A页面的onshow事件里写A的初始化数据逻辑。
14 | - 5、undefined 当作字符串处理 if(xxx == "undefined") 【后期版本迭代优化了】
15 | - 6、遇到奇怪的问题(如样式等)先重启工具,百试不爽
16 | - 7、不支持本地web字体(需要使用线上字体),经测试发现一些安卓就是不能正常显示。几经折腾才发现原来还要存放字体的服务器要支持跨域。尼玛,手机上调试也不报错,差点放弃web字体了。卡了好久,坑.............
17 | - 8、本地资源无法通过 css 获取 可以使用网络图片,或者 base64,或者使用 `` 标签
18 | - 9、不能直接操作 Page.data 【避免在直接对 Page.data 进行赋值修改,请使用 Page.setData 进行操作才能将数据同步到页面中进行渲染】
19 | - 10、数字键盘用 type="digit"
20 | - 11、已用 https,但报无法建立与该服务器的安全连接是什么情况【需要 nginx 配置一下 https 的加密标准为tls1.2及以上】
21 | - 12、wx.setStorage(OBJECT) 【目前每个小程序限制5M】
22 | - 13、数据监控【微信后台:事实访问次数/昨日概况/累计访问用户数/TOP受访页】
23 | - 14、微信调试神器,ngrok,见 ngrok
24 | - 15、view 添加点击效果[需要开启hover效果]:
25 |
26 | ```html
27 |
28 | ```
29 | - 16、用户授权调试方法【开发工具-》清除手机授权数据 (缓存-清除手机授权数据) 】
30 | - 17、安卓手机上小程序第一次加载时候首页时候, onshow方法会莫名其妙加载两遍,而同样在iphone下却不会,由于需要在onshow里面触发获取用户信息,所以系统加载两次onshow会导致后台报错。。。
31 | - 18、禁止页面下拉: 设置 "disableScroll": true 。
32 | - 19、安卓下会出现getAppConfig:fail,无法获取userInfo。微信问题,下载最新的微信安装包
33 | - 20、后台不能接受POST数据,但是可以接收GET请求参数
34 |
35 | ```json
36 | url: url,
37 | data: data,
38 | method: "POST",
39 | dataType: "json",
40 | header: {
41 | 'content-type': 'application/x-www-form-urlencoded' //==> 此处若为application/json则服务端无法获取POST的参数
42 | }
43 | ```
44 |
45 | - 21、小程序第一次启动用户拒绝授权后,下一次无法唤起授权弹框,默认记住上一次用户的选择。暂时没有找到解决方法,微信也没有相关解析。【2017-01-10】
46 | 微信更新了api(wx.authorize(OBJECT)),支持唤起授权弹框【2017-07-05】
47 | - 22、跳转到有tabbar的页面一定要用 wx.switchTab().这个在各个群里几乎每天都有人问到!!!
48 | - 22、绑定开发者/体验者时记得去手机上确认邀请。(超多人问)
49 |
50 | 
51 |
52 | - 23、 微信后台更新了request合法域名,可以直接去微信开发工具-->项目-->配置信息-->刷新,立马生效。
53 | - 24、 小程序官方没有提供java版登录信息解密示例,可以用这个demo java版解密demo
54 | - 25、 使用wx:for遍历的时候最好加上wx:key="{{item.id}}",如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略,但是如果遍历的数组会发生改变,则有可能导致数据顺序会改变。
55 |
56 | 
57 |
58 | - 26、小程序开发页面便利之处在于rpx, 所以设计稿建议用iphone6尺寸。flex布局可以参考这篇
59 | - 27、微信小程序的会默认监听文件变化,然后自动刷新。但不足的是每次都是全量刷新,而不是模块的热替换,反而会影响开发速度,尤其对于喜欢频繁Command + S的开发者,你会发现你的小程序在不断的刷新。[@MinJieLiu](https://github.com/MinJieLiu)
60 | - 28、微信小程序自 基础库 `1.6.4 `开始支持了`web-view`组件,即在小程序支持了嵌入网页的能力,但是使用的时候发现在开发者工具中不能显示网页,手机预览却可以【升级微信客户端最新版本】。原因是所使用的基础库不支持`web-view`组件,可通过选择最新的基础库解决。如下:
61 |
62 | 
63 |
64 | - 29、 不支持H5和小程序通信,不能通过本地存储之类的手段打通, 如果硬是需要携带参数,可以尝试在`web-view` url 中携带,但是不推荐,H5可以使用公众号授权。web-view开放的能力(网页需嵌入jssdk): [网页中支持的JSSDK接口](https://mp.weixin.qq.com/debug/wxadoc/dev/component/web-view.html):
65 | - 30、web-view 目前不支持微信支付
66 | - 31、小程序中`try...catch`语句中`catch`部分使用`throw`抛出错误在更外层的`try...catch`无法捕获到
67 |
68 | 
69 |
70 | #### 二、小程序开发前相关配置
71 |
72 | - 1、登录--->管理员扫二维码-->设置-->开发设置-->生成AppSecrect
73 | - 2、服务器配置
74 | 登录--->管理员扫二维码-->设置-->开发设置-->服务器域名-->扫二维码
75 | - 3、绑定开发者
76 | 用户身份-->开发者-->二维码 开发者最多10人
77 | - 4、绑定体验者
78 | 用户身份-->体验者-->二维码扫描 体验者20人
79 |
80 |
81 | #### 三、小程序发布
82 |
83 | 发布只能用管理员账号。步骤如下:
84 |
85 | - 开发工具中退出开发者账号
86 | - 管理员扫码登录开发者工具,上传-->微信后台设为体验版本-->审核-->发布
87 |
88 | 注意: 审核时间不定,2-6天
89 |
90 | #### 四、审核不通过原因收集
91 | - 1、小程序简介没有介绍小程序功能
92 | - 2、类目与页面提供的内容不一致
93 | - 3、小程序提供的服务和内容必须是正式的,不能以测试内容提交,多次以测试内容提交
94 | - 4、含有声音视频内容,请补充相关对应类目
95 | - 5、首页图片与文字有互相重叠,建议优化
96 | - 6、搜索框及少数下才能选中,页面评论点击无响应,页面图片分辨率尺寸失真
97 | - 7、部分图片显示被压缩体检不好
98 | - 8、有账号体系的小程序,除自有登录方式,必须支持微信授权登录
99 | - 9、必须登录才能使用的服务,请提供测试账号
100 | - 10、存在虚拟物品在线交易, ios系统需要走IAP,小程序暂不支付,请留意后续
101 | - 11、小程序服务类目所对应的页面中的核心内容必须与该类目一致。
102 | - 12、必须保证用户在该页面能使用该服务类目,不得隐藏,不得进行多次跳转
103 | - 13、不得展示和推荐第三方小程序。示例:不能做小程序导航,不能做小程序链接互推,小程序排行榜等
104 | - 14、小程序的页面内容中,存在诱导类行为,包括但不限于诱导分享、诱导添加、诱导关注公众号、诱导下载等,要求用户分享、添加、关注或下载后才可操作的程序,含有明示或暗示用户分享的文案、图片、按钮、浮层、弹窗等的小程序,通过利益诱惑诱导用户分享、传播的小程序,用夸张言语来胁迫、引诱用户分享的小程序,强制或诱导用户添加小程序的,都将会被拒绝;
105 | - 15、 禁止视频、音乐、语音等多媒体的自动播放
106 | - 16、 如果小程序有账户系统,必须提供能正常使用且易于发现的“退出”账户选项
107 | - 17、小程序内容不能包含赌博、竞猜和抽奖的。
108 | - 18、小程序的页面内容中,不能存在测试类内容;示例:算命,抽签,星座运势等。
109 |
110 | [其他微信小程序平台常见拒绝情形](https://developers.weixin.qq.com/blogdetail?action=get_post_info&lang=zh_CN&token=1592986236&docid=c53fb90c11590a1b86c109b4006fae27)
111 |
112 | #### 五、文档及社区
113 | - 1、[官方文档](https://mp.weixin.qq.com/debug/wxadoc/dev/index.html?t=201715)
114 | - 2、[官方Q&A](https://mp.weixin.qq.com/debug/wxadoc/dev/qa.html?t=201715)
115 | - 3、[官方社区](https://developers.weixin.qq.com)
116 | - 4、[小程序接入指南](https://developers.weixin.qq.com/blogdetail?action=get_post_info&lang=zh_CN&token=1592986236&docid=bb39a3dfd5f9c7070f9e2ec3c0f7f68a)
117 | - 5、[小程序常见FAQ](https://developers.weixin.qq.com/blogdetail?action=get_post_info&lang=zh_CN&token=1592986236&docid=2fcdb7794d48c59f7624f53e94d0ae22)
118 |
119 | #### 六、code
120 |
121 | - 1、封装微信发起请求接口,登录失效默认自动发起登录请求
122 |
123 | ```js
124 | /**
125 | * 发起的是 HTTPS 请求
126 | * @pram url: 请求地址,协议必须为https
127 | * @pram data 请求参数请求参数
128 | * @param success 请求成功回调
129 | * @param fail 请求失败回调
130 | * @param complete 请求完成(成功或者失败)回调
131 | */
132 | function request(url, data, success, fail, complete) {
133 | var _url = url,
134 | _data = data,
135 | _success = success,
136 | _fail = fail,
137 | _complete = complete;
138 |
139 | wx.request({
140 | url: url,
141 | data: data,
142 | method: "POST",
143 | dataType: "json",
144 | header: {
145 | 'content-type': 'application/x-www-form-urlencoded',
146 | 'Client-Agent': getSystemInfo(),
147 | 'WX-SESSION-ID': wx.getStorageSync(constant['WX-SESSION-ID']) //每次请求带上登录标志
148 | },
149 | success: function(res) {
150 | if(res.data.code == "-9999") { //会话失效重新登录
151 | requestLogin(function(){
152 | constant['NUM_TRY_LOGIN'] ++;
153 | //设置请求上限,防止重复提交并死循环
154 | if(constant['NUM_TRY_LOGIN'] < constant['LIMIT_NUM_TRY_LOGIN']) {
155 | request(_url, _data, _success, _fail, _complete);
156 | }
157 | });
158 | return;
159 | }
160 | if(res.data.code == "0") {
161 | if(typeof _success == "function") {
162 | _success(res.data);
163 | }
164 | } else {
165 | wx.showToast({title: res.data.msg, icon: 'loading', duration: 2000});
166 | return;
167 | }
168 | },
169 | fail: function(res) {
170 | if(typeof _fail == "function") {
171 | _fail(res);
172 | }
173 | if(typeof _fail == "string") { //请求失败的弹框提示
174 | wx.showToast({title: _fail, icon: 'loading', duration: 2000});
175 | }
176 | },
177 | complete: function(res) {
178 | if(typeof _complete == "function") {
179 | _complete(res);
180 | }
181 | }
182 | });
183 | }
184 | ```
185 | - 2、请求登录接口
186 |
187 | ```js
188 | /**
189 | * 请求登录,获取用户相关信息
190 | * @param callback
191 | */
192 | function requestLogin(callback) {
193 | var _callback = callback;
194 | wx.login({
195 | success: function (event) {
196 | // 获取到请求码,继续请求用户的基本信息
197 | if(event.code) {
198 | var code = event.code;
199 | wx.getUserInfo({
200 | success: function (res) {
201 | var data = {
202 | code: code,
203 | encryptedData: res.encryptedData,
204 | iv: res.iv,
205 | signature: res.signature,
206 | rawData: res.rawData
207 | }
208 | var url = domain + "/wx_xxx"; //请求登录地址
209 | request(url, data,
210 | function(res){ //success
211 | if(res.code == "0") {
212 | //此处可以将服务端返回的登录状态保存起来
213 | wx.setStorageSync(constant['WX-SESSION-ID'], res.object.sessionId);
214 | if(typeof _callback == "function") {
215 | _callback();
216 | }
217 | }
218 | },
219 | function(res){ //fail
220 | wx.showToast({title: '请求登录失败',icon: 'loading', duration: 2000});
221 | }
222 | );
223 | },
224 | fail: function(res) {
225 | //用户拒绝授权
226 | if(res.errMsg == "getUserInfo:cancel" || res.errMsg == "getUserInfo:fail auth deny") {
227 | wx.redirectTo({ //跳转至未授权页面
228 | url: '../xxx-page/xxx-page'
229 | });
230 | }
231 | }
232 | })
233 | } else {
234 | wx.showToast({title: '微信登录失败',icon: 'loading', duration: 2000});
235 | }
236 | },
237 | fail: function(res) {
238 | wx.showToast({title: '微信登陆失败!',icon: 'loading', duration: 2000});
239 | }
240 | });
241 | }
242 | ```
243 |
244 | 
245 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | title:
2 | description: [微信小程序踩坑集合]
3 | show_downloads: false
4 | google_analytics:
5 |
--------------------------------------------------------------------------------
/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ page.title | default: site.title }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |