初撸WordPress小记

撸这个 WordPress 站有一段时间了,也解决了一些比较蛋疼的问题,大晚上的一股鸡血上脑,就撸了一发小文,记录一下这段时间解决的几个比较有用的问题。

1. 中文标签和分类的问题
偶然发现直接点击中文标签或分类链接,wordpress 是根本找不到相关内容的。相当于访问 http://ftxtool.org/index.php/category/技术随笔/ 的时候服务器给我返回的是 404 ,然而,使用 http://ftxtool.org?category=技术随笔 传参数的方式却可以正常访问到,估计是 url 地址重定向时候的问题。
所以,网上能找到一类解决方案就是修改 rewrite.php 的代码。然而,就像某个复制粘贴的博主说的那样,根本没有找到别人说的那块代码在哪。应该是经过很多版本的更新,那部分代码早就不一样了,然而这种复制粘贴的精神依然屹立,永不过时。
另外一个解决方案,是修改 class-wp.php ,把 $_SERVER[‘PATH_INFO’] 和 $_SERVER[‘REQUEST_URI’] 转码,把 GBK 转成 UTF-8 。然而,经过测试好像并没有什么卵用。
方案三,修改别名。把别名改成一小串英文,亲测有效。具体操作方法就是:
仪表盘→分类目录/标签→选一个具体的分类或标签名字,点下边的快速编辑→别名(随便写个英文的名字),然后更新就好了。
方案四,插件。方案三虽然可以解决问题,但是每个标签都要手动改一遍还是有些蛋疼的。找来找去找到个插件,用起来还不错。插件名叫:IIS Chinese Tag Permalink 直接去安装插件里搜索这个名字就能找到。目前用起来还没啥问题,应该算比较靠谱的一个方案。然而还是有个别标签一直 404 ,只能通过改别名的办法解决,不知道有没有更好一些的插件可以解决这个问题。

2. sitemap
赵家百度的 sitemap 插件简直渣到爆,跟 google 的 XML-Sitemap 插件简直没法比。从设置页面就已经被秒成渣渣了。最蛋疼的是生成 sitemap 文件,我去点了按钮也没反应,一直是:没有生成 sitemap 文件。麻痹的没有任何提示了,只好去代码里下 log。
原来生成文件是在 wordpress 的跟目录,代码注释里竟然叫我把目录整个权限设成777。简直日了狗,你家运维都是这么干活的么?
然后,还是手动在根目录创建了个 sitemap 文件,然后加个写权限,就可以用了。
然而,还是 google 家的 sitemap 好使。自己自动生成好之后还能自动通知 google 和 bing 。

3. 友情链接
新版本添加友情链接还是蛮蛋疼的,网上能搜到的基本上都是老版本的方案,或者 link manager 插件,但是插件并不好使。真心想不明白,这帮人复制来复制去也没有经过验证,然后还被搜索引擎排的那么靠前。
新版本添加链接其实很简单,只要在侧边栏加上一个自定义菜单就可以了:
外观→自定义→小工具→侧边栏
点击【添加小工具】选择【自定义菜单】
然后选上自己添加好链接的菜单就可以了。

然而怎么添加一个菜单呢?
外观→菜单
点击【创建新菜单】
然后 填一个名字
然后 在【自定义链接】中添加
能看懂提示文字基本上不会错。

注意:这个菜单不要勾选 主菜单 。

libgit2使用教程(二) git add

主要内容:
1. git add <path>
2. git add .

示例代码:sample2

一、 open
上一篇初始化了一个 git 仓库,接下来开始使用我们本地的 git 仓库。几乎所有的操作都需要使用一个 git_repository 指针,所以第一步,我们先初始化这个指针。
如果是新创建一个仓库的话,使用上一篇的 git_repository_init 就可以了。如果是一个已有的仓库呢?
就用 git_repository_open 这个函数。这个函数很简单,两个参数,参数一是返回 git_repository 指针,参数二是仓库地址。

二、 add
add 就开始有些复杂了,我们要分情景讨论这个事。
1. add 指定文件
通过官方API我们找到了一个函数 git_index_add_bypath ,主要意思就是:通过指定 path 添加一个文件到 index [附一]
只有两个参数,参数一是 git_index 指针,参数二是指定文件的路径。
所以,我们要先拿到 git_index 的指针:

拿到了 index 指针,就可以 add 了:

然后运行一下,没有报错,然后到我们的仓库调用 git status 看一下。

On branch masterInitial commit

Untracked files:
(use “git add …” to include in what will be committed)

file

nothing added to commit but untracked files present (use “git add” to track)

file 并没有被 add 进来,是什么原因呢?

其实,git_index_add_bypath 操作并没有失败,只不过它是对内存的操作,在程序结束的时候,并没有把内存中的 index 写到磁盘,如果要把 index 写到磁盘,需要调用一个函数:

好了,目前完整的 add 的代码就是:

2. add 全部
使用函数 git_index_add_all 可以把没有添加到 index 的改动全部添加到 index 中。写一个简单的测试代码:

有时候对于参数不知道到底要传什么,就可以先传个 null 或者 0,运行看程序给你报什么错,再根据具体的错误找解决方案。不过显然,这段代码的运行结果是符合我们的预期的,我们对这个仓库中所有文件的修改都被 add 到 index 中了。说明参数二 paths 传空,就相当于命令:
git add .
那么,后边两个参数的作用是什么的?
倒数第二个参数是一个函数指针 git_index_matched_path_cb ,而最后一个参数则是传递给这个回调函数的参数。
所以我们给 index 添加改动的时候,是可以通过这个回调函数获得一些信息的:

这个回调的参数一是有改动的文件路径,参数二是 git_index_add_all 的第二个参数中和这个文件路径匹配的 pathspec ,第三个参数是前边提到过的自定义参数。
最重要的是它的返回值:
0:正常添加
正数:跳过添加这个文件的改动
负数:直接报错返回,这个时候 git_index_add_all 将直接返回,返回值就是我们这个回调函数的返回值。

所以这个回调函数可以让我们根据自己的情况对批量添加做一个过滤。
然后,翻回头再说一下 git_index_add_all 的第二个参数[附二]。他是一个路径规则,不满足这个规则的文件将直接被跳过。也不会触发上边那个回调函数。满足规则的文件和对应的那一项规则,将成为回调函数的参数一和参数二。
所以调用的代码是这个样子的:

 

附一、解释一下 index
index 可以理解为一个存储区,存放被 add 进来的“改动”,add 的文件的改动被添加到 index ,commit 操作把这个 index 添加到本地仓库,可以通过 git rm —cached 从 index 中删除指定“文件”。只要不 commit 我们玩儿的就一直是同一个 index 。

附二、git_strarray
git_strarray 是一个结构体:

strings 是一个字符串数组,count 是这个数组有多少个元素。
这个结构后边会经常用到,与多个路径相关的参数和返回值,都会使用这个结构。

libgit2使用教程(一)实现 git init

主要内容:
1. 使用 libgit2 的准备工作
2. 构建和运行
3. 初始化一个 git 仓库

示例代码:https://github.com/XiaochenFTX/libgit2_samples

进入正题

开始直接到 libgit2 的 readme 我们首先需要从那里获取一些有用的信息。
官网:https://libgit2.github.com/
API:http://libgit2.github.com/libgit2/
虽然官方文档写的挺水的,不过毕竟可以获得信息的途径就这么少,所以凑合着也还能用。

接下来提到了两个非常重要的函数, init 和 shutdown ,必须保证在任何操作之前调用初始化:

释放 init 申请的资源,使用:

这样就可以开始第一个程序了

ok 打完收工。

先把它跑一下看看,如果可以正常跑完,就说明所有的构建基本上都没啥问题了。

当然,这并没有什么卵用。接下来来搞个有意义的代码来结束这篇。
第一个例子就实现一下 git init

打完收工。

当然,良好的编程习惯,在最后不要忘了释放资源。

接口的详细说明可以去查官方的 API 我会在必要的地方对一些我觉得比较重要的东西进行说明。

git_repository_init 的第一个参数是将初始化好的 git_repository 指针返回,这个库的接口基本上都是这个风格的,以后就不再提这个事了。
这个函数会返回一个错误码,返回值为 0 表示执行成功,小于 0 表示有错误。所以可以通过判断返回值得方式来确定函数调用是否成功。
想知道具体报错信息,可以调用 giterr_last() 这个函数返回一个 git_error 结构体指针。

klass 对应 git_error_t 的枚举值,用于说明是哪部分出的问题。message 是一个人类可以看懂的的说明信息。开发中遇到问题可以把这个信息打印出来,对找问题有很大帮助。

最终完成 sample1 的代码就是这个样子

最后解释一下为什么要用 goto
很多同学在学习 C 语言的时候,如果遇到不负责任的老师,都会强调不要用 goto 这个东西,更有甚者干脆讲都不讲。而具体原因不外乎:会让代码逻辑混乱,可读性差,不好调试
当然,造成这些后果,都是在“如果用不好”的前提下的。然而,我认为这个语言特性真的不是不值一提的垃圾,把 goto 用好在一定程度上是可以让代码更美观、更简洁、更易读。
随便举个例子,比如跳出多层循环,难道还要引入一个外层变量再逐层判断吗?在这种情况下那种方式可读性更高?
还有就是在错误发生的情况下,直接跳到函数结尾进行清理。如果不使用 goto ,我见过几种奇葩方案,最突出的应该是用 do{}while(0); 吧,这样强行为了不用 goto 而产生的奇葩行为,我只能呵呵了。
所以,我推荐在必要的时候使用 goto 来使代码更清晰、简洁。当然,也不是随便瞎用,任何工具都有其最佳适用范围,不能矫枉过正。

附一、代码中引用 libgit2:
在根目录的 CMakeLists.txt 中把相关工程文件夹都用 add_subdirectory 加进来,并且指定 libgit2 的 include 为引用目录

在需要链接这个库的工程中使用 target_link_libraries 链接上 libgit2
就像我们的 sample1 中这样

有些环境下会报找不到 -lssh2 的错误:
ld: library not found for -lssh2
只要在根目录的 CMakeLists.txt 中加上一句:

这样简单的构建系统就搭建好了,可以开始写代码了
使用其他 IDE 的话,直接用 cmake 导出对应的工程,在自己创建的工程中引入就可以了。
不太推荐直接编译好库放到工程里使用,我自己试了之后发现它用到的几个第三方库还需要自己手动构建再引用。

附二、示例代码的使用:

1. 从 github 上拉代码

2. 使用 cmake 导出熟悉的 IDE 工程,或者直接构建运行

Xcode:

Visual Studio:

直接构建:

我使用的 IDE 是 Clion ,使用 Clion 导入工程也可以直接使用

MacOS OpenGL窗口程序的正确打开方式

当小白挖开gl渲染这个坑的时候,最先遇到的问题一定是窗口。然后就是虐死强迫症系列的剧情。
教程最多的一定是glut系列,然而,放到Xcode里一片黄,原因是苹果在未来要不支持这玩意了。再之后就是glew、glfw等一堆库,到这个时候一个没什么基础的小白玩家应该已经有流失的想法了。
这篇博客主要介绍怎么直接搞出一个干净的glview窗口程序,简简单单的开始OpenGL的新手引导。

然后也可以解决一些问题:
1. 如何创建一个OpenGL窗口
2. glut的警告问题
3. 可以使用4.0以上版本的OpenGL
4. 对于非小白玩家而言可能第3条是最重要的

废话少说,书归正传:
第一步、创建工程
1. 新建一个Cocoa Application工程
130298
2. 拖一个OpenGL View 替换掉原来的默认View
582077
这样这个窗口就可以启动运行了。

第二步、写代码
1. 新建一个Cocoa Class,选择继承自 NSOpenGLView
306506
2. 把上边建好的GLView关联上我们自己的类
742882
这样就可以在我们自己类中调用渲染代码了。

第三步、支持GL4.1
需要实现的函数:
initWithCoder
defaultPixelFormat
prepareOpenGL
drawRect

重点就是在初始化部分,需要设置一下属性才能真正的支持4.1

这样就是一个可以正常撸的GL窗口程序了。非常适合强迫症玩家入门使用,编译器完全没有警告。

在这就不贴完整代码了。有一个可运行的程序,在github上。
https://github.com/XiaochenFTX/glFirst

curl在Android系统卡死的问题

问题描述:
调用 curl 获取消息头的时候,发现程序卡住不动了。代码如下:

经测试发现,不做任何设置,做一次发送,同样会卡死。

解决方案:

经过反复试验,在请求的时候设置写数据回调,就可以正常执行了。

 

 

具体原因不详,暂时没有精力去读它的代码。我猜卡死的问题与代码本身关系不大,暂时比较怀疑编译库的工具链。由于之前遇到过 ndk 编译出的 sscanf 等函数调用卡死,所以这货暂时列为A级怀疑对象。

C++ 如何让自己的类支持foreach

首先,我们先看看使用 foreach 的时候,都发生了什么。

新建一个类,根据经验,我们 for 一个对象应该是这样的:
所以,迭代器, beigin(), end() 应该是会用得到的,我们做个试验:
Generator.h

Generator.cpp
main.cpp
运行结果:

 

说明我们想的没错,foreach 跟上边的 for 的行为是一样的。
插个体外话,(发现字打错了,不过不改了,还是挺哏儿的)
1. 之前以为 for (const auto i : g) 会调用 const 版本的 cbegin cend ,然而 并不会。
2. iterator 叫什么名字都没什么所谓,起名叫 红太阳 也ok。
接下来,处理一下迭代器:(我想确认一下丫具体被如何操 做)

 

输出结果:

已经足够说明问题了,自己把剩下的细节补充上就好了。

总结一下要点:
1. begin() end()
2. 迭代器
3. 迭代器重载 !=
4. 迭代器重载 前++
5. 迭代器重载 *(解引用)

iOS命令行打包的坑

最近在搞自动打包的时候,不小心踩到了了烂水果没有来得及擦干净的菊花。

总结一下经验教训:
1.技术
找不到ResourceRules.plist
类似这样的警告:
Warning: –resource-rules has been deprecated in Mac OS X >= 10.10! /tmp/QYFSJIvu7W/Payload/XX.app/ResourceRules.plist: cannot read resources
经过我缜密的调(gu)查(ge)取(bai)证(du),大致上可以猜测是烂水果更新了签名机制后并没有更新整套命令行工具。
秘密就藏在……
执行以下命令:

定位到 PackageApplication 然后用随便什么文本编辑器打开

搜索 ResourceRules ,定位到之后,清理掉与她有关的参数,整成这样:

就这样。

亲测有效,目前尚未发现副作用。
参考文献:(临时找来凑数的)
2.
签名验证失败:
Program /usr/bin/codesign returned 1 :
resource envelope is obsolete 这个错误
stackoverflow 上大神给出的解决方案就是在 codesign 验证的时候,加上 –no-strict (不严格验证?这尼玛确实不报错了,然而……总之就是不报错了)
具体操作方式,也是向上边一样,修改 PackageApplication
找到 —verify 那行 加上 –no-strict 参数:

参考资料: