2020-06
18

BlogBus 2 WordPress – by xrspook

By xrspook @ 19:50:07 归类于: 扮IT

为什么要学习python?因为我见识过python有多牛逼,简单一个脚本文件,轻量级的东西实现强大的功能。因为要做XML文件的格式转换,所以我觉得我要学好python。Think Python 2看到第14章,我就转向去研究10年多以前网友写的BlogBus转WordPress的python脚本。之所以要研究,因为当时的WordPress格式和现在不一样,用以前的脚本转换出来的东西已经没办法直接导入到现在的WordPress里了。再去找写代码的那些人,有些网站还在,但有些已经消失了。我不能等待别人拯救我,我只能自己拯救自己。

我需要转换格式的是“回到过去——Betty迷的独白”和“Mi Internacional Cielo”,这两个旧BlogBus站点和我的主站“我的天”不一样,虽然里面有不少我原创的东西,但我从四面八方搜集回来的内容也不少。当时的BlogBus默认编辑界面是富文本,我看上去觉得格式没问题大概就可以了,但实际上格式是有问题的。从五湖四海搜集回来的文字里面怎么可能不夹杂各种格式,那些东西在富文本编辑下可能看不出来,但在源代码界面一团糟。如果当年我复制粘贴的时候有先去记事本过渡一下就不会有那么多的问题。所以除了要转换BlogBus和WordPress的标签以外我还要筛选删除那些坏事的源代码。

经过接近一周的努力,我终于整出来了。运行下面的python3脚本,如果能顺利完成,自动生成出新的XML文件,用官方途径导入WordPress 5.4.2是完全没有问题的,但我只测试了我自己的两个blog,是不是兼容其它我不知道。因为转换blog我是有自己的想法的,所以脚本中有一些个性化的东西,比如我把blog的标题变成了分类,把原来的分类变成了标签。脚本中有大量的反转义替换,主要是为了人去看CDATA的时候不太头晕迷糊,因为我那两个旧blog里有大量的西班牙语字符,不同的编码下,BlogBus的导出文件里有些被转义了有些没有。那些转义了的放到WordPress里不知道WordPress会不会转回来,我试过标题被BlogBus转义之后WordPress不会转回来,看得我云里雾里。因为转义很头痛,所以除了少数几个内容,有可能被转义的文字都被我用CDATA包裹了起来。

脚本不是我一个人的功劳,我只是在当年网友脚本的基础上做了调整,使之适配python3和WordPress 5.4.2。

我的脚本:xbus2wp.py (PS:下面脚本330行的《/p》是什么鬼怪!WordPress的脚本插件在搞什么!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
'''
***使用说明***
终端界面输入xbus2wp.py bus.xml xrspook。其中:
xbus2wp.py为脚本名字,bus.xml为BlogBus导出文件,xrspook为博主名字,3个参数以空格分开
若运行无误,输出的文件名为[原文件名_xbus2wp.xml]
脚本基于python3,适配WordPress 5.4.2(2020-06-18)
'''
 
import re, sys, getopt, datetime
from xml.dom import minidom
from time import time
 
def convert(inputFileName, owner, order='asc'):
    """"""
    try:
        xmldoc = minidom.parse(inputFileName)
    except Exception as e:
        print ('Fail.')
        print (e)
        print ('Please repair or delete invalid token like "& < >" there.')
        sys.exit(1)
 
    bus = xmldoc.documentElement
    logs = bus.getElementsByTagName('Log')
 
    dom = minidom.Document()
    rss = dom.createElement('rss') # rss是root,根元素
    dom.appendChild(rss)      
    rss.setAttribute('version', '2.0')
    rss.setAttribute('xmlns:content', 'http://purl.org/rss/1.0/modules/content/')
    rss.setAttribute('xmlns:wfw', 'http://wellformedweb.org/CommentAPI/')
    rss.setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/')
    rss.setAttribute('xmlns:wp', 'http://wordpress.org/export/1.0/')
    channel = dom.createElement('channel')
    rss.appendChild(channel)
    wxr_version = dom.createElement('wp:wxr_version') # 加入wxr戳,无戳无法进行WordPress导入
    channel.appendChild(wxr_version)
    wxr_version_node = dom.createTextNode('1.1')
    wxr_version.appendChild(wxr_version_node)
 
    busname = bus.getElementsByTagName('BlogName')[0] # 提取原BlogBus名字
    busname_text = getElementData(busname).replace(' ', '_')
 
    # create a list to contain items instead of appending them to
    # channel directly in order to sort them of lately according to order.
    if order == 'desc':
        item_list = []
    else:
        item_list = None
 
    for log in logs:
        title = log.getElementsByTagName('Title')[0]
        title_text = getElementData(title)
        content = log.getElementsByTagName('Content')[0]
        content_text = getElementData(content)
        logdate = log.getElementsByTagName('LogDate')[0]
        pubdate = getElementData(logdate)
        writer = log.getElementsByTagName('Writer')[0]
        creator = owner # BlogBus的writer根本没包含元素!
        category = getElementData(log.getElementsByTagName('Sort')[0])
        tagi = log.getElementsByTagName('Tags')[0]
        tags = getElementData(tagi).split(' ')
        new_tags = unique_tag(category, tags) # 新的wp标签里包含了原BlogBus里的分类与标签
        comments = log.getElementsByTagName('Comment')
 
        #-----
        item = dom.createElement('item')
 
        # handle title
        title_element = createElement(dom, 'title', title_text, 'cdata')
        item.appendChild(title_element)
 
        # handle type
        type_element = createElement(dom, 'wp:post_type', 'post', 'cdata')
        item.appendChild(type_element)
 
        # handle pubdate
        pubdate_element = createElement(dom, 'pubDate', convertPubDate(pubdate))
        item.appendChild(pubdate_element)
 
        # handle creator
        creator_element = createElement(dom, 'dc:creator', creator, 'cdata')
        item.appendChild(creator_element)
 
        # handle categories with domain
        category_element = createElement(dom, 'category', busname_text, 'cdata') # 把BlogBus标题设置为分类,因为我要合并多个旧blog
        category_element.setAttribute('domain','category')
        category_element.setAttribute('nicename', busname_text)
        item.appendChild(category_element)
 
        # handle tags
        for tag in new_tags:
            tag = tag.replace('&ntilde;', 'n')
            tag = tag.replace('summary_of_BLF', 'summary_of_BLF(from_rincondebetty)')
            tag = tag.replace('summary_of_EcoModa', 'summary_of_EcoModa(from_rincondebetty)')
            category_element = createElement(dom, 'category', tag, 'cdata')
            category_element.setAttribute('domain','post_tag')
            category_element.setAttribute('nicename', tag)
            item.appendChild(category_element)
 
        # handle content
        content_element = createElement(dom, "content:encoded", content_text, 'cdata')        
        item.appendChild(content_element)
 
        # handle post_date
        post_date_element = createElement(dom, "wp:post_date", pubdate)
        item.appendChild(post_date_element)
 
        # handle status
        status_element = createElement(dom, "wp:status", 'publish')
        item.appendChild(status_element)
 
        # handle comments
        if comments:
            commentElements = createComments(dom, comments)
            for commentElement in commentElements:
                item.appendChild(commentElement)
 
        if item_list != None:
            item_list.append(item)
        else:
            channel.appendChild(item)
 
    if item_list:
        item_list.reverse()
        for m in item_list:
            channel.appendChild(m)
 
    global filename # 输出设置
    output = filename + '_xbus2wp.xml'
    f = open(output ,'wb+')
    import codecs
    writer = codecs.lookup('utf-8')[3](f)
    dom.writexml(writer, '', ' ' * 4, '\n', encoding='utf-8')
    writer.close()
 
def unique_tag(category,tags): # 只保留唯一的标签
    category = category.replace(' ', '_')
    l = category.split() + tags
    new_l = []
    for item in l:
        if item not in new_l and item != '(from_rincondebetty)':
            new_l.append(item.replace(' ', '_')) # 替换空格为下划线
    return new_l
 
def getElementData(element): # 获取节点数据
    """"""
    data = ''
    for node in element.childNodes:
        if node.nodeType in (node.TEXT_NODE, node.CDATA_SECTION_NODE):
            data += node.data
    return data
 
def createComments(dom, comments):
    """"""
    l = []
    count = 0
    for comment in comments:
        count += 1 # 每篇文章的评论序号,没有序号,评论只能导入每篇最后一条
        email = comment.getElementsByTagName('Email')[0]
        homepage = comment.getElementsByTagName('HomePage')[0]
        name = comment.getElementsByTagName('NiceName')[0]
        content = comment.getElementsByTagName('CommentText')[0]
        date = comment.getElementsByTagName('CreateTime')[0]
        comment_element = createCommentElement(count, dom, email, homepage, name, content, date)
        l.append(comment_element)
    return l
 
def createCommentElement(count, dom, email, homepage, name, content, date):
    """"""
    comment_author = getElementData(name)
    comment_author_email = getElementData(email)
    comment_author_url = getElementData(homepage)
    comment_date = getElementData(date)
    comment_content = getElementData(content)
 
    comment_id_element = createElement(dom, 'wp:comment_id', str(count))
    comment_author_element = createElement(dom, 'wp:comment_author', comment_author)
    comment_author_email_element = createElement(dom, 'wp:comment_author_email', comment_author_email)
    comment_author_url_element = createElement(dom, 'wp:comment_author_url', comment_author_url)
    comment_date_element = createElement(dom, 'wp:comment_date', comment_date)
    comment_date_gmt_element = createElement(dom, 'wp:comment_date_gmt', comment_date)
    comment_content_element = createElement(dom, 'wp:comment_content', comment_content, 'cdata')
    comment_approved_element = createElement(dom, 'wp:comment_approved', '1')
 
    # make the comment element
    comment_element = dom.createElement('wp:comment')
    comment_element.appendChild(comment_id_element)
    comment_element.appendChild(comment_author_element)
 
    # validate email and url
    validEmail = validateEmail(comment_author_email)
    if (validEmail):
        comment_element.appendChild(comment_author_email_element)
 
    validUrl = validateUrl(comment_author_url)
    if (validUrl):
        comment_element.appendChild(comment_author_url_element)    
 
    comment_element.appendChild(comment_date_element)
    comment_element.appendChild(comment_date_gmt_element)
    comment_element.appendChild(comment_content_element)
    comment_element.appendChild(comment_approved_element)
 
    return comment_element
 
def createElement(dom, elementName, elementValue, type='text'): #建立节点标签和节点
    """"""
    global owner
    tag = dom.createElement(elementName)
    if elementValue.find(']]>') > -1:
        type = 'text'
    if type == 'text':
        text = dom.createTextNode(elementValue)
    elif type == 'cdata':
        elementValue = elementValue.replace('&amp;', '&')
        elementValue = elementValue.replace('&lt;', '<')
        elementValue = elementValue.replace('&gt;', '>')
        elementValue = elementValue.replace('&apos;', '\'')
        elementValue = elementValue.replace('&quot;', '"')
 
        # 大量替换与我的旧blog有各种编码的西班牙语字符有关
        elementValue = elementValue.replace('&copy;', '') # 版权标志
        elementValue = elementValue.replace('&nbsp;', '') # 空格
        elementValue = elementValue.replace('&ldquo;', '“') # 左双引号
        elementValue = elementValue.replace('&rdquo;', '”') # 右双引号
        elementValue = elementValue.replace('&lsquo;', '‘') # 左单引号
        elementValue = elementValue.replace('&rsquo;', '’') # 右单引号
        elementValue = elementValue.replace('&acute;', '´') # 单引号
        elementValue = elementValue.replace('&hellip;', '...') # 省略号
        elementValue = elementValue.replace('&mdash;', '—') # 破折号
        elementValue = elementValue.replace('&middot;', '·') # 分隔号
        elementValue = elementValue.replace('&deg;', '°') # 单位度
        elementValue = elementValue.replace('&iexcl;', '¡') # 西班牙语反叹号
        elementValue = elementValue.replace('&iquest;', '¿') # 西班牙语反问号
        elementValue = elementValue.replace('&ntilde;', 'ñ') # 西班牙语n
        elementValue = elementValue.replace('&Ntilde;', 'Ñ') # 西班牙语N
        elementValue = elementValue.replace('&aacute;', 'á') # 西班牙语a
        elementValue = elementValue.replace('&eacute;', 'é') # 西班牙语e
        elementValue = elementValue.replace('&iacute;', 'í') # 西班牙语i
        elementValue = elementValue.replace('&oacute;', 'ó') # 西班牙语o
        elementValue = elementValue.replace('&uacute;', 'ú') # 西班牙语u
        elementValue = elementValue.replace('&Aacute;', 'Á') # 西班牙语A
        elementValue = elementValue.replace('&Eacute;', 'É') # 西班牙语E
        elementValue = elementValue.replace('&Iacute;', 'Í') # 西班牙语I
        elementValue = elementValue.replace('&Oacute;', 'Ó') # 西班牙语O
        elementValue = elementValue.replace('&Uacute;', 'Ú') # 西班牙语U
        elementValue = elementValue.replace('&Atilde;', 'Ã') # 西班牙语A~
        elementValue = elementValue.replace('&ordf;', 'ª') # 西班牙语上标a
        elementValue = elementValue.replace('&ordm;', 'º') # 西班牙语上标o
 
        elementValue = elementValue.replace('<!--msnavigation-->', '')
        elementValue = elementValue.replace('博主', owner)
        elementValue = elementValue.replace('<i>', '')
        elementValue = elementValue.replace('</i>', '')
        elementValue = elementValue.replace('<br /><br />', '<br />')
 
        elementValue = re.sub(r"(?:<\?xml.*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<[TDSFHI].*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<\/[TDSFHI].*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<P.*?>)", "<p>", elementValue)
        elementValue = re.sub(r"(?:<(table|tbody|tr|td|div|span|img|script|font|hr|object|param).*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<\/(table|tbody|tr|td|div|span|img|script|font|object).*?>)", "", elementValue)
        elementValue = re.sub(r"\n", "", elementValue) # 把替换造成的空行删除
 
        text = dom.createCDATASection(elementValue)
    tag.appendChild(text)
    return tag
 
def convertPubDate(date, timediff='+0000'):
    """
    convert 2003-08-22 16:01:56
    to Thu, 23 Aug 2007 05:47:54 +0000
    """
    year, mon, day = int(date[:4]), int(date[5:7]), int(date[8:10])
    time = date[11:]
    aday = datetime.datetime(year, mon, day)
    d = {'1':'Mon', '2':'Tus', '3':'Wen', '4':'Thur', '5':'Fri', '6':'Sat', '7':'Sun'}
    m = {'1':'Jan', '2':'Feb', '3':'Mar', '4':'Apr', '5':'May', '6':'Jun',
         '7':'Jul', '8':'Aug', '9':'Sep', '10':'Oct', '11':'Nov', '12':'Dec'}
    weekday = d[str(aday.isoweekday())]
    month = m[str(mon)]
    pubdate = "%s, %d %s %s %s %s" % (weekday, day, month, year, time, timediff)
    return pubdate
 
def validateEmail(email):
    '''
    '''
    pattern = r'^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$'
    p = re.compile(pattern)
    m = p.match(email)
    if m:
        return True
    else:
        return False
 
def validateUrl(url):
    '''
    '''
    pattern = r'^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$'
    p = re.compile(pattern)
    m = p.match(url)
    if m:
        return True
    else:
        return False
 
def main(argv=None):    
    global filename
    global owner
 
    if argv is None:
        argv = sys.argv
    # parse command line options
 
    args = sys.argv[1:]
    order='asc'
    if (len(args) == 2):
        print ('Converting...'),
        sys.stdout.flush()
        start = time()
        filename = args[0].replace('.xml', '')
        owner = args[1] # BlogBus没把博主名字输出,只能手动
        convert(args[0], args[1], order)
        end = time()
        print ('Done. Elapse %g seconds.' % (end - start))
 
if __name__ == "__main__":
    sys.exit(main())
</p>
2020-03
22

折腾不同版本的WXR

By xrspook @ 22:09:44 归类于: 烂日记

我只是想把自己从前的东西重新拿出来,原来这也会很难,这是我完全没想到的。要找回那些尘封10年的文档,并不算太难,翻一下电脑也就找到了,虽然有点坎坷,因为当时备份的时候,我没有标注是哪个网站的,xml都放在一起,我以为那都是我主站的,后来,同一个日期不同的文件大小才让我觉得有蹊跷。xml文档找到了,接着要把它转化为WordPress的格式。当年用来转换文档的脚本找不到了,翻遍家里电脑的各个盘都没找到。之所以在家的电脑找不到,是因为当时干这事我是在单位完成的。所以理论上单位的电脑应该有,但是因为换过电脑,我也清理过同步盘,所以会不会也因此清理掉呢?这个我不确定。我觉得,在我转格式的时候,我仍然在用Dropbox,里面的很多东西我的确已经清理了,于是这也很好解释,为什么我家里电脑的Dropbox文件夹里找不到那个脚本。家里的电脑没有,单位的电脑可能有,但还有一种可能性,我把那上传到网盘,于是就把那同步软件里撤掉了。我只会上传到两个地方,一个是百度,一个是115。115打开很麻烦,我也懒得下载打开它的工具。百度上果然就有我要找的东西,但当我想把整个文件夹下载回来的时候,问题严重了,那里居然有4000多个文件。下大文件的时候度娘就很慢,下小文件的时候度量更慢,那是直接10KB以下的速度。我直接去网页版的度娘找到我要的东西,不在客户端里等它慢慢下载了。

东西下载回来以后,我再翻查我的日志,我需要安装一个Python。我默认安装的是现在最新的版本3.7.7,但运行脚本以后却发现才刚刚开始读取脚本,就马上报错。查找原因,原来是版本之间的语法差异。才刚刚开始就错,要运行完整个脚本,我真不知道还得修改我根本不懂的语法。所以,我把最新的Python卸载掉了,重新安装当时我就在那个版本下转换的2.6.5。2.6.5是一个什么概念?这意味着时光倒流10年。

出乎我意料,软件装好以后,我几乎没遇到困难就可以把BlogBus的文档成功转为了WordPress的格式。在下载Python的时候,我顺便下载了XAMPP,同样下载的是最新的版本。前段时间我才刚用过,觉得挺爽。我也下载了最新版的WordPress的5.3.2。同时把导入插件也装。当我试图上传,已经转过格式的xml是,上传报错。原来这才是噩梦的开始!不同版本的WordPress里的xml格式各不相同,几乎可以这么说,越往后越严格越来越严格了。于是我又安装了WordPress 3.9和2.8。3.9的WordPress在PHP 7之下马马虎虎可以运行,2.8是直接连数据库都连不上…… 于是我甚至不能从通过低版本的WordPress N轮导入导出拯救世界……

没办法,我只能研究我手头上的xml,看看和现在的标准版差多少。首先,必备填写一个WXR的版本号。在旧版本里,这条规则是这是不存在的,所以要手动加入。同样需要手动加入的就是,即文件类型,因为现在的WordPress把文章分成了post和page。把这些搞定以后,基本上正文就可以导进去了,但是分类和标签还是不行。因为现在的分类和标签,WordPress使用的是一个叫做nice name的东西,你必须在分类和标签那里,加上这个标注0才能识别的出来。评论那里,当年就试过在2.8的版本里面评论正常,但是在2.9里面,有评论的话会只剩下一条评论。研究发现,那是因为评论有了一个id号。BlogBus转码过来的东西没有id号,所以大概东西就自动覆盖了。除了这些BlogBus和WordPress之间的格式问题以外。我的文章里还有格式的=问题,因为有些东西,不完全是我自己的东西,好些是我从网络上搜集回来的。当时我保存了网页,在BlogBus发布的时候直接复制到可视化编辑器,所以格式也带入了。如果当时我懂得先把东西贴到记事本,然后再剪切粘贴一次,就不会存在这种问题。除了格式以外,从前的blog里还有图片,但经过这么多年,图片都已经失效了,链接摆在那里只会浪费加载时间和访客的期待,所以我要把图片链接也尽可能去掉。有些图片链接是我没办法去掉的,因为用正则筛选的时候会遇到一些很屌丝的句子,到了某个点,就卡住了,但实际上那并不是这个标签的结束。

搞清那些规则,总结出我的对策。一次又一次查找替换,一次又一次导入删除再导入。花了一整个下午加半个晚上的时间,我总算搞定了从前BlogBus上的BLF!文章238篇齐全,评论56条也齐全!!!其中可能会有一些小格式上毛病,但是那并不是共性的问题,后续还得靠运气慢慢修改。

非常有必要记录一下我在Notepad++上做的WordPress不同版本xml转换操作

/*操作开始*/

普通替换《channel》为《channel》《wp:wxr_version》1.1《/wp:wxr_version》 /*WP XML共性问题*/
普通替换《category domain=”category”》为《category domain=”tag”》
普通替换《dc:creator》《/dc:creator》
为《dc:creator》《![CDATA[xrspook]]》《/dc:creator》《wp:post_type》《![CDATA[post]]》《/wp:post_type》《category domain=”category”》《![CDATA[回到过去——Betty迷的独白]]》《/category》 /*《/wp:post_type》前是WP XML共性问题*/
普通替换《BR》《BR》为《BR》
普通替换《!–msnavigation–》为无
普通替换[summary_of_BLF]为[summary_of_BLF(from_rincondebetty)]
普通替换[summary_of_EcoModa]为[summary_of_EcoModa(from_rincondebetty)]
普通替换《category domain=”tag”》《![CDATA[(from_rincondebetty)]]》《/category》为无
普通替换[Yo soy Betty, la Fea]为[Yo_soy_Betty,_la_fea]
普通替换[JEA’s Writting]为[JEA’s_Writting]
普通替换”博主”为”xrspook”
普通替换《i》为无
普通替换《/i》为无

正则替换category\”》《\!\[CDATA\[(.*?)\]为category\” nicename=\”\1\”》《\!\[CDATA\[\1\] /*WP XML共性问题*/
正则替换tag\”》《\!\[CDATA\[(.*?)\]为post_tag\” nicename=\”\1\”》《\!\[CDATA\[\1\] /*WP XML共性问题*/
正则替换《[TDSFHI].*?》为无
正则替换《/[TDSFHI].*?》为无
正则替换《P.*?》为《P》
正则替换《(table|tbody|tr|td|div|span|img|script|font|hr).*?》为无
正则替换《/(table|tbody|tr|td|div|span|img|script|font).*?》为无

《wp:comment》《/wp:comment》中增加《wp:comment_id》1《/wp:comment_id》,id数字递增 /*WP XML共性问题*/

/*操作结束*/

注:请自行替换《》为<>,用尖括号那是全部都挂掉无法显示的节奏啊啊啊

这个是一次死去活来的经历啊啊啊啊啊啊啊啊啊啊啊啊!奇怪的知识又增长了不少……

2020-03
20

偶遇VSCode

By xrspook @ 9:27:33 归类于: 烂日记

昨天晚上但我吃完饭回到宿舍,拖完地要去办公室之前,我跟书桌上的外婆说,今晚总算没那么多板上的任务,我会早点回来。结果我还是很晚才回宿舍,甚至比平时还要晚,因为我洗完澡的时候已经超过了晚上11点。昨天跟之前几天不一样,因为昨天单位有卸船作业,所以我还得在手提电脑上忙一阵单位的事情。我很痛恨自己的拖延症,跟之前几晚相比,昨晚我的确是很闲的,但正是因为我很闲,所以我就去看了一下自己订阅的东西,结果就发现一个,很好玩的跨平台,出自微软,轻量级的编程软件。之前基本上可以这么说,我没用过编程软件,一直用的最多的是Notepad++,但那只是个代替Windows记事本的工具。的确很便携,而且在处理代码的时候也有高亮显示,字体大小和格式很自由,体积很小,我已经用了很多年,一直觉得很爽,因为用那个东西,有后悔药。即便我按了保存,还是可以后退很多步,至于一共能后退多少,我还真没研究过,装上插件以后,可以有跟多形式的自动保存,比如当光标离开软件以后,东西就自动保存了。又或者我可以设置,多少时间就保存一次。写代码这种东西,最慌的就是改完以后才发现,没改之前更好,但是软件不能后退,没有后悔药。跟Office软件比起来,Notepad++的后悔药好用多了。因为Office软件一旦按了保存,之前的东西就后退不了了。而且Notepadd++打开文件的速度非常快,即便是很大的数据文件也没有问题,比如说,几十MB的XML文件。为什么会有那种东西?其实那个就是我WordPress导出的数据,是我10多年来blog的日志数据。我不知道如果那些东西拿去出书的话,那本书得有多少页。其实我还真有想过会不会有一天无聊地把自己的blog拿去出书。但为什么要出纸质版的书呢?电子书其实也行。把我的blog静态打包下来,就是一本电子书。

回到Notepad++加上,虽然那个东西可以用来写代码,但跟专业的写码软件比起来,还是挺不方便的。虽然其实Notepadd++也有不少插件,但是跟别人的插件比起来,好像还是欠缺点什么。如果纯粹是文字,不是代码的话,我觉得它非常优秀了。比如说我经常用来核对字幕哪里修改了。之前我并不觉得Notepad++不适合用来写代码,直到昨天我看到了那个VSCode以后。在那里保存一个后缀为HTML的文件以后,你只需在那里输入一个东西,之前之后的那些格式全部都自动生成了,而且全部都已经标记好颜色,做好了缩进。那个东西自带了emmet功能,快速写码变得易如反掌,因为只需要写一点点东西,一大串成对的代码就出来了,于是,妈妈再也不用担心我丢三落四,因为成对的代码会自动出来,代码可以出来,我觉得自动缩进不会有啥状况。一直我都在搞blog,我一直都只是在做前端的设计,看到这些功能以后,我简直震惊了,用这个东西写码,只要你有思路。只要你有灵感,写一个网页相当快捷简单。不过绝大多数时候,我觉得前端设计还是需要一些脑洞的,比如说你根本没想到可以那样做的话,你怎么可能写得出来。

因为看到那个让我兴奋的软件,而且还是便携的,直接解压使用,无需安装(但是很大,解压后200多MB),所以洗澡的时候我考虑过要不要再写一个WordPress模板,那个blog用来存放我从前做过的那些blog。那些不是我主站的blog,比如说BLF的、JEA的、以及ADR的。那里的东西有些不是我的,但是很大一部分都是我磨出来的。曾经,我在那里倾注了非常多心血。那是我曾经的兴趣所在。那些东西是我人生的一部分,但是,他们以前的家已经消失了。BlogBus没有了,点点也没有了……我觉得我应该让他们重生。

写一个网站的前端需要灵感,但网站的核心是内容。首先,我要考虑怎么把BlogBus和点点导出来的数据转化为WordPress可以理解的内容。

2020-03
17

页码导航,搞定!

By xrspook @ 10:44:11 归类于: 烂日记

昨天突然发现,备份下来的COLOR3模板的截图是2014年的,所以这个模板是不是没有10年历史这么悠久呢?WordPress我用了10年,但这个模板用了多少年?我真的没有仔细翻查过资料。(发布这篇blog之前我又验证了一下,COLOR3的确是2010年的作品)。就怪当年设计好模板之后,我没有在上面标注时间,现在完成改版以后,我会在CSS上标注上版本的更新信息。我会不会把这个模板用一辈子呢?真不知道,又或者不知道多年以后我不用WordPress了呢。

昨天我把之前用插件解决的页码导航也实现了,但实际上不知道从第几个版本的WordPress开始,已经内置了页码导航,但很多个版本的官方标准模板上面的只有上一页和下一页。上一页跟下一页的设置非常原始,对内容有非常多的blog来说,这简直就是把人杀死的节奏,虽然有一点观察力的访客会发现,除了主页是没有页码以外,只要你翻到第2页,从网址上你就已经能看到页码了,所以接下来你只需要天马行空地在那里输入你想要的数字,就能跳转到那个地方,但问题是,对一个路人甲来说。页面只显示了上一页跟下一页,但最后一页是多少呢?难道还要搞一个猜谜游戏?于是,这又让我想起了那个什么逼近法。用靠谱的页码导航就不会有这种烦恼,那些算数问题全部都留给服务器了,因为任何一个导航页面都会有首页和最后一页的锚点(最后一页其实是算出来的),上一页跟下一页的锚点也是有的,当然如果那是最前头和最末末,会缺少了其中一个方向的锚点。中间的页面要展示多少个锚点,系统预留了控制点。我不知道这么好用的功能,为什么WordPress不把它光明正大读放出来,当然,没有很光明正大放出来的还有很多神奇的函数,比如,里面有很好几个预设参数,没有评论的时候可以显示一个信息,一条评论的时候可以显示一个信息,多条评论的时候可以显示一个信息,不允许评论的时候又可以有另外一个信息。对中文用户来说,一条评论和多条评论从语句设定上没有区别,但是,对英文来说,就有一个单数跟复数的区别,WordPress是外国人开发的,当然就会有把这两种分开来预设。昨天我没花什么功夫就找到了WordPress原生自带的那个页码导航,这纯粹是我运气好,万一我搜索了好几个小时才找到呢?找到那个原生的函数以后,我只需要对里面的东西进行格式化。WordPress肯定也知道。他们没有格式过的界面是没办法直接使用的,所以早就放好了各种关键字,只要你对那些东西进行合适的处理,就能做出你想要的效果。

在使用原生页码导航之前我查看了WordPress最新官方模板2020的代码,那个模板用的就是原生的页码导航,但经过高度的格式化处理。不知道现在的开发理念是不是区块管理,所以在2020模板里一个php又引用了另外无数的php。一个模板里有好几个文件夹,一个文件夹里有好几个php。当你打开一个以后,你不得不又继续跳到另外一个,继续有可能还要到其它地方。我是个很懒惰的人,基本上我把我需要引用的函数都丢到我的functions.php里。之前的COLOR3有好几个sidebar相关的php,但现在通过用函数判断,我直接把它们都缩到一个里。十年之前的COLOR3,基本上我都只是对CSS动刀,但现在,我会自己研究php里面的判断。其实无论是哪个编程语言,我觉得最终都可以变成简单的几条。第1条是分配,第2条是判断,第3条是循环,第4条是输出。基本上可以这么说,所有编程语言都在玩这几条,尤其是判断跟循环,不断地组合搭配,就能得出你想要的东西。现在回想起来,当年学习C语言的时候,冒泡法基本上可以被称作是终极大boss。当时老师觉得那是教学大纲里最高端的了,搞懂了那个,其它基本上不成问题,而冒泡法这种东西,连老师自己上课的时候也说得小心翼翼,因为她自己也没达到可以随便就脱口而出谈冒泡法的境界。估计现在再让我去冒泡法,我会得心应手很多。

大概当我彻底完成COLOR3模板升级以后,我会重新开始学习Java。几年前那本深入浅出学习Java的书看得我直接投降,因为后面的习题我就没做对几个,如果现在再去看的话,估计会有一些长进了。

2020-03
16

背景颜色

By xrspook @ 11:58:14 归类于: 烂日记

又花了一个下午的时间,我总算把超链接给搞定了。之前我就已经发现了那么个现象,如果我为一个图片做超链接,而那个超连接的默认的格式有悬停背景色的时候,无论我怎么整,图片下方都会有一条线,问题只是,那条线是粗还是细。昨天我遇到的问题是我需要在三个64*64像素的小图片上面做超链接。三个的图片完全没有文字,让人很绝望的无论我如何操作,那三个图片下面都有一个64*17的超链接方块,从颜色看来,那就是我在那个区域设定的超链接背景颜色。无论我怎么设置,分辨出来的东西还是会有那个颜色。之所以会是17,是因为我把文字的高度设定为16px。最终我终于记起了一条规定,如果之前你没有对某个元素设定规则的话,后面你可以重新为这个元素设定格式,但有些如果前面你已经设定了格式,后面,你又要推翻这个格式,并把它变成无格式的话,这是不可能的,除非我祭出大招“!important”。我在某片区域对超连接设定了背景颜色。但是在某些特定的情况之下,我又要把背景颜色去掉,单纯的background-color:transparent做不到的,但假如暴力的“!important”就可以。要去掉那个背景颜色,在不加“!important”的前提下,我把超链接的颜色设置为和那片区域背景颜色一致,所以颜色虽然存在,但就不会被看到了,但这么低端的做法CSS维护的时候就麻烦了。这个让我纠结了一个下午的事从前我也就结果,但因为太久远,已经忘记了。

昨天我匆匆把翻新过的COLOR3模板上线,感觉还不错。其实我也没改什么,主要是一些功能完善以及格式上的东西。我还专门找了一个色卡的网站去研究到底背景要用什么颜色。最普通的是浅灰色,但是那实在太普通了,然后我把黄色,橙色,粉色,蓝色,绿色,这几种很浅的马卡龙颜色都试了一遍,感觉有点怪怪的。说不准到底是为什么,反正就是和主体区域的白色混搭起来会有点刺眼。另外一个让我纠结的就是版头的颜色,之前我用的是纯黄色和纯橙色。这两个颜色加起来会让人有酸酸甜甜的热烈感觉,但是跟那些浅色混在一起,会莫名地让人觉得刺眼。以前模板的背景颜色是白色,同样也是橙色和黄色之所以没感觉刺眼,是因为我在所有板块外面都加了5px的边框,而这一次我把5px的边框全部都去掉了。之所以要去掉边框,是因为某一次,不知道谁留言说,我那些黑色的边框让人觉得辣眼睛。看到那条评论的时候,我马上实验在网页上实时修改掉那些边框,但只是单纯去掉边框,就像PS掉大熊猫的黑眼圈一样,怪怪的。当我对版头和背景颜色一筹莫展的时候,我顺手写了个纯黑色背景上去,出乎我意料,效果非常好,简直是让人有惊艳的感觉!外围黑色让核心部分的内容更加突出提神。因为高对比度,5px的黑色边框根本不需要存在。除了黑色以外,我也在网站上实时测试了其他颜色,发现用深色效果都挺好,所以我可以根据心情,随便换颜色。比如喜庆的时候换个纯红色。几乎可以这么说,只要是偏深的颜色都适合当我的背景颜色,因为主体区域我用的是鲜艳的颜色。

我不是一个美工,我总喜欢把东西弄得很整齐而已。真正的美工大概都很在乎意境,所以我永远都到达不了他们的境界。

© 2004 - 2024 我的天 | Theme by xrspook | Power by WordPress