前置教程:

之前弄了一些插件,糖果屋的群友们也找我问了问,所以我就顺便写了个文章介绍一下这些插件吧。

1.日历插件

这个插件还不支持pjax,重回主页后会不显示,使用pjax的小伙伴们慎用(我的大部分东西都不支持pjax)或者自己修改js。

效果如下:

1660889640604

1660889644091

注:如果你一天写了多个文章,它只会跳转到你那天的第一篇文章。

2022.12

发现有严重的性能问题,已不建议使用

这个日历是我之前在网上意外搜到的,搜了很久。为了防止它不在了,所以就放在这里。

我做了什么?

  1. 修复部分bug
  2. 适配本站AcrylicUI
  3. 适配pjax

教程

这个日历的实现比较简单,放出教程:

PUG部分

首先添加一些pug,添加 [blogRoot]/themes\butterfly\layout\includes\widget\card_calendar.pug
,然后编辑以下内容:

1
2
3
4
5
6
7
if theme.aside.card_calendar.enable
.card-widget.card-calendar
.card-content
.item-headline
i.fas.fa-calendar
span= _p('文章日历')
div#calendar.widget

然后在主pug中引入,编辑 [blogRoot]\themes\butterfly\layout\includes\widget\index.pug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#aside-content.aside-content
//- post
if is_post()
- const tocStyle = page.toc_style_simple
...

else
//- page
...
.sticky_layout
if showToc
include ./card_post_toc.pug
+ !=partial('includes/widget/card_calendar', {}, {cache: true})
if theme.weather.enable
.card-widget.card-weather(style='width:100%,height:270px')
...

如果你想要在文章页中也显示,按照这样编辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#aside-content.aside-content
//- post
if is_post()
...
if showToc && tocStyleVal
...
else
...
!=partial('includes/widget/card_history', {}, {cache: true})
+ !=partial('includes/widget/card_calendar', {}, {cache: true})
.sticky_layout
...

else
//- page
...

主题配置

然后修改主题配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
aside:
enable: true
hide: false
button: true
mobile: false # display on mobile
position: left # left or right
archives: true
card_author:
enable: true
...
card_announcement:
enable: true
content: ...
+ card_calendar:
+ enable: true
...

JS部分

接下来添加js:

添加 [blogRoot]/themes/butterfly/source/js/languages.js:

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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
var calLanguages = {
ar: { // Arabic
months: [
'كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'
],
dayOfWeekShort: [
'ن', 'ث', 'ع', 'خ', 'ج', 'س', 'ح'
],
dayOfWeek: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت', 'الأحد']
},
ro: { // Romanian
months: [
'Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'
],
dayOfWeekShort: [
'Du', 'Lu', 'Ma', 'Mi', 'Jo', 'Vi', 'Sâ'
],
dayOfWeek: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă']
},
id: { // Indonesian
months: [
'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
],
dayOfWeekShort: [
'Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'
],
dayOfWeek: ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu']
},
is: { // Icelandic
months: [
'Janúar', 'Febrúar', 'Mars', 'Apríl', 'Maí', 'Júní', 'Júlí', 'Ágúst', 'September', 'Október', 'Nóvember', 'Desember'
],
dayOfWeekShort: [
'Sun', 'Mán', 'Þrið', 'Mið', 'Fim', 'Fös', 'Lau'
],
dayOfWeek: ['Sunnudagur', 'Mánudagur', 'Þriðjudagur', 'Miðvikudagur', 'Fimmtudagur', 'Föstudagur', 'Laugardagur']
},
bg: { // Bulgarian
months: [
'Януари', 'Февруари', 'Март', 'Април', 'Май', 'Юни', 'Юли', 'Август', 'Септември', 'Октомври', 'Ноември', 'Декември'
],
dayOfWeekShort: [
'Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'
],
dayOfWeek: ['Неделя', 'Понеделник', 'Вторник', 'Сряда', 'Четвъртък', 'Петък', 'Събота']
},
fa: { // Persian/Farsi
months: [
'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
],
dayOfWeekShort: [
'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
],
dayOfWeek: ['یک‌شنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه', 'شنبه', 'یک‌شنبه']
},
ru: { // Russian
months: [
'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
],
dayOfWeekShort: [
'Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'
],
dayOfWeek: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота']
},
uk: { // Ukrainian
months: [
'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
],
dayOfWeekShort: [
'Ндл', 'Пнд', 'Втр', 'Срд', 'Чтв', 'Птн', 'Сбт'
],
dayOfWeek: ['Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П\'ятниця', 'Субота']
},
en: { // English
months: [
'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'
],
dayOfWeekShort: [
'S', 'M', 'T', 'W', 'T', 'F', 'S'
],
dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
postsMonthTip: 'Posts published in LMM yyyy',
titleFormat: 'LMM yyyy'
},
el: { // Ελληνικά
months: [
'Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος'
],
dayOfWeekShort: [
'Κυρ', 'Δευ', 'Τρι', 'Τετ', 'Πεμ', 'Παρ', 'Σαβ'
],
dayOfWeek: ['Κυριακή', 'Δευτέρα', 'Τρίτη', 'Τετάρτη', 'Πέμπτη', 'Παρασκευή', 'Σάββατο']
},
de: { // German
months: [
'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
],
dayOfWeekShort: [
'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'
],
dayOfWeek: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag']
},
nl: { // Dutch
months: [
'januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'
],
dayOfWeekShort: [
'zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'
],
dayOfWeek: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag']
},
tr: { // Turkish
months: [
'Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'
],
dayOfWeekShort: [
'Paz', 'Pts', 'Sal', 'Çar', 'Per', 'Cum', 'Cts'
],
dayOfWeek: ['Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi']
},
fr: { //French
months: [
'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'
],
dayOfWeekShort: [
'Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'
],
dayOfWeek: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi']
},
es: { // Spanish
months: [
'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'
],
dayOfWeekShort: [
'Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'
],
dayOfWeek: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado']
},
th: { // Thai
months: [
'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
],
dayOfWeekShort: [
'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
],
dayOfWeek: ['อาทิตย์', 'จันทร์', 'อังคาร', 'พุธ', 'พฤหัส', 'ศุกร์', 'เสาร์', 'อาทิตย์']
},
pl: { // Polish
months: [
'styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień'
],
dayOfWeekShort: [
'nd', 'pn', 'wt', 'śr', 'cz', 'pt', 'sb'
],
dayOfWeek: ['niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota']
},
pt: { // Portuguese
months: [
'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
],
dayOfWeekShort: [
'Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'
],
dayOfWeek: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado']
},
ch: { // Simplified Chinese
months: [
'一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'
],
dayOfWeekShort: [
'日', '一', '二', '三', '四', '五', '六'
]
},
se: { // Swedish
months: [
'Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'
],
dayOfWeekShort: [
'Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör'
]
},
kr: { // Korean
months: [
'1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'
],
dayOfWeekShort: [
'일', '월', '화', '수', '목', '금', '토'
],
dayOfWeek: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일']
},
it: { // Italian
months: [
'Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'
],
dayOfWeekShort: [
'Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'
],
dayOfWeek: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato']
},
da: { // Dansk
months: [
'January', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'July', 'August', 'September', 'Oktober', 'November', 'December'
],
dayOfWeekShort: [
'Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'
],
dayOfWeek: ['søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag']
},
no: { // Norwegian
months: [
'Januar', 'Februar', 'Mars', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Desember'
],
dayOfWeekShort: [
'Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'
],
dayOfWeek: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag']
},
ja: { // Japanese
months: [
'1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'
],
dayOfWeekShort: [
'日', '月', '火', '水', '木', '金', '土'
],
dayOfWeek: ['日曜', '月曜', '火曜', '水曜', '木曜', '金曜', '土曜']
},
vi: { // Vietnamese
months: [
'Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'
],
dayOfWeekShort: [
'CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'
],
dayOfWeek: ['Chủ nhật', 'Thứ hai', 'Thứ ba', 'Thứ tư', 'Thứ năm', 'Thứ sáu', 'Thứ bảy']
},
sl: { // Slovenščina
months: [
'Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'
],
dayOfWeekShort: [
'Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob'
],
dayOfWeek: ['Nedelja', 'Ponedeljek', 'Torek', 'Sreda', 'Četrtek', 'Petek', 'Sobota']
},
cs: { // Čeština
months: [
'Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'
],
dayOfWeekShort: [
'Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'
]
},
hu: { // Hungarian
months: [
'Január', 'Február', 'Március', 'Április', 'Május', 'Június', 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'
],
dayOfWeekShort: [
'Va', 'Hé', 'Ke', 'Sze', 'Cs', 'Pé', 'Szo'
],
dayOfWeek: ['vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat']
},
az: { //Azerbaijanian (Azeri)
months: [
'Yanvar', 'Fevral', 'Mart', 'Aprel', 'May', 'Iyun', 'Iyul', 'Avqust', 'Sentyabr', 'Oktyabr', 'Noyabr', 'Dekabr'
],
dayOfWeekShort: [
'B', 'Be', 'Ça', 'Ç', 'Ca', 'C', 'Ş'
],
dayOfWeek: ['Bazar', 'Bazar ertəsi', 'Çərşənbə axşamı', 'Çərşənbə', 'Cümə axşamı', 'Cümə', 'Şənbə']
},
bs: { //Bosanski
months: [
'Januar', 'Februar', 'Mart', 'April', 'Maj', 'Jun', 'Jul', 'Avgust', 'Septembar', 'Oktobar', 'Novembar', 'Decembar'
],
dayOfWeekShort: [
'Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub'
],
dayOfWeek: ['Nedjelja', 'Ponedjeljak', 'Utorak', 'Srijeda', 'Četvrtak', 'Petak', 'Subota']
},
ca: { //Català
months: [
'Gener', 'Febrer', 'Març', 'Abril', 'Maig', 'Juny', 'Juliol', 'Agost', 'Setembre', 'Octubre', 'Novembre', 'Desembre'
],
dayOfWeekShort: [
'Dg', 'Dl', 'Dt', 'Dc', 'Dj', 'Dv', 'Ds'
],
dayOfWeek: ['Diumenge', 'Dilluns', 'Dimarts', 'Dimecres', 'Dijous', 'Divendres', 'Dissabte']
},
'en-GB': { //English (British)
months: [
'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'
],
dayOfWeekShort: [
'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'
],
dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
},
et: { //'Eesti'
months: [
'Jaanuar', 'Veebruar', 'Märts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'August', 'September', 'Oktoober', 'November', 'Detsember'
],
dayOfWeekShort: [
'P', 'E', 'T', 'K', 'N', 'R', 'L'
],
dayOfWeek: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev']
},
eu: { //Euskara
months: [
'Urtarrila', 'Otsaila', 'Martxoa', 'Apirila', 'Maiatza', 'Ekaina', 'Uztaila', 'Abuztua', 'Iraila', 'Urria', 'Azaroa', 'Abendua'
],
dayOfWeekShort: [
'Ig.', 'Al.', 'Ar.', 'Az.', 'Og.', 'Or.', 'La.'
],
dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata']
},
fi: { //Finnish (Suomi)
months: [
'Tammikuu', 'Helmikuu', 'Maaliskuu', 'Huhtikuu', 'Toukokuu', 'Kesäkuu', 'Heinäkuu', 'Elokuu', 'Syyskuu', 'Lokakuu', 'Marraskuu', 'Joulukuu'
],
dayOfWeekShort: [
'Su', 'Ma', 'Ti', 'Ke', 'To', 'Pe', 'La'
],
dayOfWeek: ['sunnuntai', 'maanantai', 'tiistai', 'keskiviikko', 'torstai', 'perjantai', 'lauantai']
},
gl: { //Galego
months: [
'Xan', 'Feb', 'Maz', 'Abr', 'Mai', 'Xun', 'Xul', 'Ago', 'Set', 'Out', 'Nov', 'Dec'
],
dayOfWeekShort: [
'Dom', 'Lun', 'Mar', 'Mer', 'Xov', 'Ven', 'Sab'
],
dayOfWeek: ['Domingo', 'Luns', 'Martes', 'Mércores', 'Xoves', 'Venres', 'Sábado']
},
hr: { //Hrvatski
months: [
'Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj', 'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan', 'Listopad', 'Studeni', 'Prosinac'
],
dayOfWeekShort: [
'Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub'
],
dayOfWeek: ['Nedjelja', 'Ponedjeljak', 'Utorak', 'Srijeda', 'Četvrtak', 'Petak', 'Subotagg']
},
ko: { //Korean (한국어)
months: [
'1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'
],
dayOfWeekShort: [
'일', '월', '화', '수', '목', '금', '토'
],
dayOfWeek: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일']
},
lt: { //Lithuanian (lietuvių)
months: [
'Sausio', 'Vasario', 'Kovo', 'Balandžio', 'Gegužės', 'Birželio', 'Liepos', 'Rugpjūčio', 'Rugsėjo', 'Spalio', 'Lapkričio', 'Gruodžio'
],
dayOfWeekShort: [
'Sek', 'Pir', 'Ant', 'Tre', 'Ket', 'Pen', 'Šeš'
],
dayOfWeek: ['Sekmadienis', 'Pirmadienis', 'Antradienis', 'Trečiadienis', 'Ketvirtadienis', 'Penktadienis', 'Šeštadienis']
},
lv: { //Latvian (Latviešu)
months: [
'Janvāris', 'Februāris', 'Marts', 'Aprīlis ', 'Maijs', 'Jūnijs', 'Jūlijs', 'Augusts', 'Septembris', 'Oktobris', 'Novembris', 'Decembris'
],
dayOfWeekShort: [
'Sv', 'Pr', 'Ot', 'Tr', 'Ct', 'Pk', 'St'
],
dayOfWeek: ['Svētdiena', 'Pirmdiena', 'Otrdiena', 'Trešdiena', 'Ceturtdiena', 'Piektdiena', 'Sestdiena']
},
mk: { //Macedonian (Македонски)
months: [
'јануари', 'февруари', 'март', 'април', 'мај', 'јуни', 'јули', 'август', 'септември', 'октомври', 'ноември', 'декември'
],
dayOfWeekShort: [
'нед', 'пон', 'вто', 'сре', 'чет', 'пет', 'саб'
],
dayOfWeek: ['Недела', 'Понеделник', 'Вторник', 'Среда', 'Четврток', 'Петок', 'Сабота']
},
mn: { //Mongolian (Монгол)
months: [
'1-р сар', '2-р сар', '3-р сар', '4-р сар', '5-р сар', '6-р сар', '7-р сар', '8-р сар', '9-р сар', '10-р сар', '11-р сар', '12-р сар'
],
dayOfWeekShort: [
'Дав', 'Мяг', 'Лха', 'Пүр', 'Бсн', 'Бям', 'Ням'
],
dayOfWeek: ['Даваа', 'Мягмар', 'Лхагва', 'Пүрэв', 'Баасан', 'Бямба', 'Ням']
},
'pt-BR': { //Português(Brasil)
months: [
'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
],
dayOfWeekShort: [
'Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'
],
dayOfWeek: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado']
},
sk: { //Slovenčina
months: [
'Január', 'Február', 'Marec', 'Apríl', 'Máj', 'Jún', 'Júl', 'August', 'September', 'Október', 'November', 'December'
],
dayOfWeekShort: [
'Ne', 'Po', 'Ut', 'St', 'Št', 'Pi', 'So'
],
dayOfWeek: ['Nedeľa', 'Pondelok', 'Utorok', 'Streda', 'Štvrtok', 'Piatok', 'Sobota']
},
sq: { //Albanian (Shqip)
months: [
'Janar', 'Shkurt', 'Mars', 'Prill', 'Maj', 'Qershor', 'Korrik', 'Gusht', 'Shtator', 'Tetor', 'Nëntor', 'Dhjetor'
],
dayOfWeekShort: [
'Die', 'Hën', 'Mar', 'Mër', 'Enj', 'Pre', 'Shtu'
],
dayOfWeek: ['E Diel', 'E Hënë', 'E Martē', 'E Mërkurë', 'E Enjte', 'E Premte', 'E Shtunë']
},
'sr-YU': { //Serbian (Srpski)
months: [
'Januar', 'Februar', 'Mart', 'April', 'Maj', 'Jun', 'Jul', 'Avgust', 'Septembar', 'Oktobar', 'Novembar', 'Decembar'
],
dayOfWeekShort: [
'Ned', 'Pon', 'Uto', 'Sre', 'čet', 'Pet', 'Sub'
],
dayOfWeek: ['Nedelja', 'Ponedeljak', 'Utorak', 'Sreda', 'Četvrtak', 'Petak', 'Subota']
},
sr: { //Serbian Cyrillic (Српски)
months: [
'јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'
],
dayOfWeekShort: [
'нед', 'пон', 'уто', 'сре', 'чет', 'пет', 'суб'
],
dayOfWeek: ['Недеља', 'Понедељак', 'Уторак', 'Среда', 'Четвртак', 'Петак', 'Субота']
},
sv: { //Svenska
months: [
'Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'
],
dayOfWeekShort: [
'Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör'
],
dayOfWeek: ['Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag']
},
'zh-TW': { //Traditional Chinese (繁體中文)
months: [
'一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'
],
dayOfWeekShort: [
'日', '一', '二', '三', '四', '五', '六'
],
dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
},
'zh-CN': { //Simplified Chinese (简体中文)
months: [
'一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'
],
dayOfWeekShort: [
'日', '一', '二', '三', '四', '五', '六'
],
dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
postsMonthTip: '查看yyyy年MM月的文章',
titleFormat: 'yyyy年MM月'
},
he: { //Hebrew (עברית)
months: [
'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
],
dayOfWeekShort: [
'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
],
dayOfWeek: ['ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת', 'ראשון']
},
hy: { // Armenian
months: [
'Հունվար', 'Փետրվար', 'Մարտ', 'Ապրիլ', 'Մայիս', 'Հունիս', 'Հուլիս', 'Օգոստոս', 'Սեպտեմբեր', 'Հոկտեմբեր', 'Նոյեմբեր', 'Դեկտեմբեր'
],
dayOfWeekShort: [
'Կի', 'Երկ', 'Երք', 'Չոր', 'Հնգ', 'Ուրբ', 'Շբթ'
],
dayOfWeek: ['Կիրակի', 'Երկուշաբթի', 'Երեքշաբթի', 'Չորեքշաբթի', 'Հինգշաբթի', 'Ուրբաթ', 'Շաբաթ']
},
kg: { // Kyrgyz
months: [
'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'
],
dayOfWeekShort: [
'Жек', 'Дүй', 'Шей', 'Шар', 'Бей', 'Жум', 'Ише'
],
dayOfWeek: [
'Жекшемб', 'Дүйшөмб', 'Шейшемб', 'Шаршемб', 'Бейшемби', 'Жума', 'Ишенб'
]
},
rm: { // Romansh
months: [
'Schaner', 'Favrer', 'Mars', 'Avrigl', 'Matg', 'Zercladur', 'Fanadur', 'Avust', 'Settember', 'October', 'November', 'December'
],
dayOfWeekShort: [
'Du', 'Gli', 'Ma', 'Me', 'Gie', 'Ve', 'So'
],
dayOfWeek: [
'Dumengia', 'Glindesdi', 'Mardi', 'Mesemna', 'Gievgia', 'Venderdi', 'Sonda'
]
},
ka: { // Georgian
months: [
'იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'
],
dayOfWeekShort: [
'კვ', 'ორშ', 'სამშ', 'ოთხ', 'ხუთ', 'პარ', 'შაბ'
],
dayOfWeek: ['კვირა', 'ორშაბათი', 'სამშაბათი', 'ოთხშაბათი', 'ხუთშაბათი', 'პარასკევი', 'შაბათი']
},
};

然后添加 [blogRoot]/themes/butterfly/source/js/calendar.js

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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/**
* Calendar - displays a calendar of the current month. Dates appear links if there are posts for that day.
*/
(function($) {
var aCalendar = function(language, options, object) {
var now = new Date();
var nDay = now.getDate();
var nMonth = now.getMonth();
var nYear = now.getFullYear();
var dDay = nDay;
var dMonth = nMonth;
var dYear = nYear;
var instance = object;
var allPosts = null;
var months = null;
/* Current month's posts */
var current = {
posts: [],
prev: null,
next: null
};
var currentLanguage = 'en';

initLanguage(language);

var settings = $.extend({}, $.fn.aCalendar.defaults, typeof calLanguages === 'undefined' ? {} : calLanguages[currentLanguage], options);

if (settings.root[0] !== '/') {
settings.root = '/' + settings.root;
}

if (settings.root[settings.root.length - 1] !== '/') {
settings.root += '/';
}

/**
* Initial language.
*/
function initLanguage(key) {
if (key && typeof calLanguages !== 'undefined' && calLanguages[key]) {
currentLanguage = key;
}
}

/**
* Click handler for next month arrow button.
*/
function nextMonth() {
if (dMonth < 11) {
dMonth++;
} else {
dMonth = 0;
dYear++;
}

draw();
};

/**
* Click handler for previous month arrow button.
*/
function previousMonth() {
if (dMonth > 0) {
dMonth--;
} else {
dMonth = 11;
dYear--;
}

draw();
};

/**
* Click handler for navigating to a month if there are posts.
*/
function toPostsMonth(date) {
if (date) {
dYear = date.getFullYear();
dMonth = date.getMonth();
draw();
}
}

/**
* Load current month's posts.
*/
function loadPosts() {
if (settings.single) {
loadAllPosts();
} else {
loadPostsByMonth();
}
}

/**
* Load all month's posts.
*/
function loadAllPosts() {
if (settings.url != null && settings.url != '') {
if (allPosts === null) {
$.ajax({
url: settings.url,
async: false,
success: function(data) {
allPosts = data;
initMonths(Object.keys(allPosts));
}
});
}

if (allPosts !== null) {
if (parse()) {
current.posts = allPosts[dYear + '-' + (dMonth + 1)];
}
}
}
}

/**
* Load posts by the month.
*/
function loadPostsByMonth() {
if (months === null) {
$.ajax({
url: settings.root + 'list.json',
async: false,
success: function(data) {
initMonths(data);
}
});
}

if (parse()) {
$.ajax({
url: settings.root + dYear + '-' + (dMonth + 1) + '.json',
async: false,
success: function(data) {
current.posts = data;
}
});
}
}

/**
* Initial months array.
*/
function initMonths(array) {
months = array.map(function(item) {
var ym = item.split('-');
return new Date(Date.UTC(+ym[0], +ym[1] - 1));
});
}

/**
* Parse posts month array, and set current.next and current.prev.
*
* @return if there are posts in this month, return true. ortherwise return false.
*/
function parse() {
var time = Date.UTC(dYear, dMonth);

if (months === null || months.length === 0) {
return false;
}

//If no posts in the current month, and before (or after) the current month yet not published articles, then the response to click previous month's (or next month's) event don't need to parse months array
if (current.posts.length === 0 && (current.prev === null && current.next !== null && current.next.getTime() > time || current.next === null && current.prev !== null && current.prev.getTime() < time)) {
return false;
}

current.posts = [];

for (var i = 0; i < months.length; i++) {
var cTime = months[i].getTime();
if (time === cTime) {
current.prev = i === 0 ? null : months[i - 1];
current.next = i === months.length - 1 ? null : months[i + 1];
return true;
} else if (time < cTime) {
current.prev = i === 0 ? null : months[i - 1];
current.next = months[i];
break;
} else {
current.prev = months[i];
current.next = null;
}
}

return false;
}

/**
* Format date object.
*/
function simpleDateFormat(date, fmt) {
var o = {
'LMM+': settings.months[date.getMonth()],
'MM+': date.getMonth() + 1
};

if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}

for (var k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (k === 'LMM+') ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
}
}

return fmt;
}

/**
* Draw calendar.
*
*/
function draw() {
loadPosts();
var dWeekDayOfMonthStart = new Date(dYear, dMonth, 1).getDay() - settings.weekOffset;
if (dWeekDayOfMonthStart <= 0) {
dWeekDayOfMonthStart = 6 - ((dWeekDayOfMonthStart + 1) * -1);
}

var dLastDayOfMonth = new Date(dYear, dMonth + 1, 0).getDate();
var dLastDayOfPreviousMonth = new Date(dYear, dMonth, 0).getDate() - dWeekDayOfMonthStart + 1;

var cHead = $('<div/>').addClass('cal-head');
var cNext = $('<div/>');
var cPrevious = $('<div/>');
var cTitle = $('<div/>').addClass('cal-title');
cPrevious.html(settings.headArrows.previous);
cNext.html(settings.headArrows.next);
curDate = new Date(Date.UTC(dYear, dMonth));
if (current.posts.length === 0) {
cTitle.html(simpleDateFormat(curDate, settings.titleFormat));
} else {
cTitleLink = $('<a/>').attr('href', simpleDateFormat(curDate, settings.titleLinkFormat))
.attr('title', simpleDateFormat(curDate, settings.postsMonthTip))
.html(simpleDateFormat(curDate, settings.titleFormat));
cTitle.html(cTitleLink);
}

cPrevious.on('click', previousMonth);
cNext.on('click', nextMonth);

cHead.append(cPrevious);
cHead.append(cTitle);
cHead.append(cNext);

var cBody = $('<table/>').addClass('cal');

var dayOfWeek = settings.weekOffset;
var cWeekHead = $('<thead/>');
var cWeekHeadRow = $('<tr/>');
for (var i = 0; i < 7; i++) {
if (dayOfWeek > 6) {
dayOfWeek = 0;
}

var cWeekDay = $('<th/>').attr('scope', 'col').attr('title', settings.dayOfWeek[dayOfWeek]);
cWeekDay.html(settings.dayOfWeekShort[dayOfWeek]);
cWeekHeadRow.append(cWeekDay);
dayOfWeek++;
}

cWeekHead.append(cWeekHeadRow);
cBody.append(cWeekHead);

var cFoot = $('<tfoot/>');
var cFootRow = $('<tr/>');
var cPrevPosts = $('<td/>').attr('colspan', 3);
var cPad = $('<td/>').html(' ');
var cNextPosts = $('<td/>').attr('colspan', 3);
if (current.prev) {
cPrevPosts.html(settings.footArrows.previous + settings.months[current.prev.getMonth()])
.addClass('cal-foot')
.attr('title', simpleDateFormat(current.prev, settings.postsMonthTip));
}

if (current.next) {
cNextPosts.html(settings.months[current.next.getMonth()] + settings.footArrows.next)
.addClass('cal-foot')
.attr('title', simpleDateFormat(current.next, settings.postsMonthTip));
}

cPrevPosts.on('click', function() {
toPostsMonth(current.prev);
});

cNextPosts.on('click', function() {
toPostsMonth(current.next);
});

cFootRow.append(cPrevPosts);
cFootRow.append(cPad);
cFootRow.append(cNextPosts);
cFoot.append(cFootRow);

var cMainPad = $('<tbody/>');
var day = 1;
var dayOfNextMonth = 1;
for (var i = 0; i < 6; i++) {
var cWeek = $('<tr/>');
for (var j = 0; j < 7; j++) {
var cDay = $('<td/>');
if (i * 7 + j < dWeekDayOfMonthStart) {
cDay.addClass('cal-gray');
cDay.html(dLastDayOfPreviousMonth++);
} else if (day <= dLastDayOfMonth) {
if (day == dDay && nMonth == dMonth && nYear == dYear) {
cDay.addClass('cal-today');
}

var count = {
num: 0,
keys: []
};
for (var k = 0; k < current.posts.length; k++) {
var d = new Date(Date.parse(current.posts[k].date));
if (d.getDate() == day) {
count.keys[count.num++] = k;
}
}

if (count.num !== 0) {
var index = count.keys[0];
var cLink = $('<a>').attr('href', current.posts[index].link).attr('title', current.posts[index].title).html(day++);
cDay.append(cLink);
} else {
cDay.html(day++);
}
} else {
cDay.addClass('cal-gray');
cDay.html(dayOfNextMonth++);
}

cWeek.append(cDay);
}

cMainPad.append(cWeek);
}

cBody.append(cWeekHead);
cBody.append(cFoot);
cBody.append(cMainPad);

$(instance).html(cHead);
$(instance).append(cBody);
}

return draw();
};

$.fn.aCalendar = function(Lang, oInit) {
return this.each(function() {
return aCalendar(Lang, oInit, $(this));
});
};

// plugin defaults
$.fn.aCalendar.defaults = {
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
dayOfWeekShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
postsMonthTip: 'Posts published in LMM yyyy',
titleFormat: 'yyyy LMM',
titleLinkFormat: '/archives/yyyy/MM/',
headArrows: {previous: '<span class="cal-prev"></span>', next: '<span class="cal-next"></span>'},
footArrows: {previous: '« ', next: ' »'},
weekOffset: 0,
single: true,
root: '/calendar/',
url: '/calendar.json'
};

}(jQuery));
$(document).ready(function () {
$("#calendar").aCalendar("zh-CN");
});
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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/**
* Calendar - displays a calendar of the current month. Dates appear links if there are posts for that day.
*/
(function($) {
var aCalendar = function(language, options, object) {
var now = new Date();
var nDay = now.getDate();
var nMonth = now.getMonth();
var nYear = now.getFullYear();
var dDay = nDay;
var dMonth = nMonth;
var dYear = nYear;
var instance = object;
var allPosts = null;
var months = null;
/* Current month's posts */
var current = {
posts: [],
prev: null,
next: null
};
var currentLanguage = 'en';

initLanguage(language);

var settings = $.extend({}, $.fn.aCalendar.defaults, typeof calLanguages === 'undefined' ? {} : calLanguages[currentLanguage], options);

if (settings.root[0] !== '/') {
settings.root = '/' + settings.root;
}

if (settings.root[settings.root.length - 1] !== '/') {
settings.root += '/';
}

/**
* Initial language.
*/
function initLanguage(key) {
if (key && typeof calLanguages !== 'undefined' && calLanguages[key]) {
currentLanguage = key;
}
}

/**
* Click handler for next month arrow button.
*/
function nextMonth() {
if (dMonth < 11) {
dMonth++;
} else {
dMonth = 0;
dYear++;
}

draw();
};

/**
* Click handler for previous month arrow button.
*/
function previousMonth() {
if (dMonth > 0) {
dMonth--;
} else {
dMonth = 11;
dYear--;
}

draw();
};

/**
* Click handler for navigating to a month if there are posts.
*/
function toPostsMonth(date) {
if (date) {
dYear = date.getFullYear();
dMonth = date.getMonth();
draw();
}
}

/**
* Load current month's posts.
*/
function loadPosts() {
if (settings.single) {
loadAllPosts();
} else {
loadPostsByMonth();
}
}

/**
* Load all month's posts.
*/
function loadAllPosts() {
if (settings.url != null && settings.url != '') {
if (allPosts === null) {
$.ajax({
url: settings.url,
async: false,
success: function(data) {
allPosts = data;
initMonths(Object.keys(allPosts));
}
});
}

if (allPosts !== null) {
if (parse()) {
current.posts = allPosts[dYear + '-' + (dMonth + 1)];
}
}
}
}

/**
* Load posts by the month.
*/
function loadPostsByMonth() {
if (months === null) {
$.ajax({
url: settings.root + 'list.json',
async: false,
success: function(data) {
initMonths(data);
}
});
}

if (parse()) {
$.ajax({
url: settings.root + dYear + '-' + (dMonth + 1) + '.json',
async: false,
success: function(data) {
current.posts = data;
}
});
}
}

/**
* Initial months array.
*/
function initMonths(array) {
months = array.map(function(item) {
var ym = item.split('-');
return new Date(Date.UTC(+ym[0], +ym[1] - 1));
});
}

/**
* Parse posts month array, and set current.next and current.prev.
*
* @return if there are posts in this month, return true. ortherwise return false.
*/
function parse() {
var time = Date.UTC(dYear, dMonth);

if (months === null || months.length === 0) {
return false;
}

//If no posts in the current month, and before (or after) the current month yet not published articles, then the response to click previous month's (or next month's) event don't need to parse months array
if (current.posts.length === 0 && (current.prev === null && current.next !== null && current.next.getTime() > time || current.next === null && current.prev !== null && current.prev.getTime() < time)) {
return false;
}

current.posts = [];

for (var i = 0; i < months.length; i++) {
var cTime = months[i].getTime();
if (time === cTime) {
current.prev = i === 0 ? null : months[i - 1];
current.next = i === months.length - 1 ? null : months[i + 1];
return true;
} else if (time < cTime) {
current.prev = i === 0 ? null : months[i - 1];
current.next = months[i];
break;
} else {
current.prev = months[i];
current.next = null;
}
}

return false;
}

/**
* Format date object.
*/
function simpleDateFormat(date, fmt) {
var o = {
'LMM+': settings.months[date.getMonth()],
'MM+': date.getMonth() + 1
};

if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}

for (var k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (k === 'LMM+') ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
}
}

return fmt;
}

/**
* Draw calendar.
*
*/
function draw() {
loadPosts();
var dWeekDayOfMonthStart = new Date(dYear, dMonth, 1).getDay() - settings.weekOffset;
if (dWeekDayOfMonthStart <= 0) {
dWeekDayOfMonthStart = 6 - ((dWeekDayOfMonthStart + 1) * -1);
}

var dLastDayOfMonth = new Date(dYear, dMonth + 1, 0).getDate();
var dLastDayOfPreviousMonth = new Date(dYear, dMonth, 0).getDate() - dWeekDayOfMonthStart + 1;

var cHead = $('<div/>').addClass('cal-head');
var cNext = $('<div/>');
var cPrevious = $('<div/>');
var cTitle = $('<div/>').addClass('cal-title');
cPrevious.html(settings.headArrows.previous);
cNext.html(settings.headArrows.next);
curDate = new Date(Date.UTC(dYear, dMonth));
if (current.posts.length === 0) {
cTitle.html(simpleDateFormat(curDate, settings.titleFormat));
} else {
cTitleLink = $('<a/>').attr('onclick', `pjax.loadUrl('${simpleDateFormat(curDate, settings.titleLinkFormat)}')`)
.attr('title', simpleDateFormat(curDate, settings.postsMonthTip))
.html(simpleDateFormat(curDate, settings.titleFormat));
cTitle.html(cTitleLink);
}

cPrevious.on('click', previousMonth);
cNext.on('click', nextMonth);

cHead.append(cPrevious);
cHead.append(cTitle);
cHead.append(cNext);

var cBody = $('<table/>').addClass('cal');

var dayOfWeek = settings.weekOffset;
var cWeekHead = $('<thead/>');
var cWeekHeadRow = $('<tr/>');
for (var i = 0; i < 7; i++) {
if (dayOfWeek > 6) {
dayOfWeek = 0;
}

var cWeekDay = $('<th/>').attr('scope', 'col').attr('title', settings.dayOfWeek[dayOfWeek]);
cWeekDay.html(settings.dayOfWeekShort[dayOfWeek]);
cWeekHeadRow.append(cWeekDay);
dayOfWeek++;
}

cWeekHead.append(cWeekHeadRow);
cBody.append(cWeekHead);

var cFoot = $('<tfoot/>');
var cFootRow = $('<tr/>');
var cPrevPosts = $('<td/>').attr('colspan', 3);
var cPad = $('<td/>').html('&nbsp;');
var cNextPosts = $('<td/>').attr('colspan', 3);
if (current.prev) {
cPrevPosts.html(settings.footArrows.previous + settings.months[current.prev.getMonth()])
.addClass('cal-foot')
.attr('title', simpleDateFormat(current.prev, settings.postsMonthTip));
}

if (current.next) {
cNextPosts.html(settings.months[current.next.getMonth()] + settings.footArrows.next)
.addClass('cal-foot')
.attr('title', simpleDateFormat(current.next, settings.postsMonthTip));
}

cPrevPosts.on('click', function() {
toPostsMonth(current.prev);
});

cNextPosts.on('click', function() {
toPostsMonth(current.next);
});

cFootRow.append(cPrevPosts);
cFootRow.append(cPad);
cFootRow.append(cNextPosts);
cFoot.append(cFootRow);

var cMainPad = $('<tbody/>');
var day = 1;
var dayOfNextMonth = 1;
for (var i = 0; i < 6; i++) {
var cWeek = $('<tr/>');
for (var j = 0; j < 7; j++) {
var cDay = $('<td/>');
if (i * 7 + j < dWeekDayOfMonthStart) {
cDay.addClass('cal-gray');
cDay.html(dLastDayOfPreviousMonth++);
} else if (day <= dLastDayOfMonth) {
if (day == dDay && nMonth == dMonth && nYear == dYear) {
cDay.addClass('cal-today');
}

var count = {
num: 0,
keys: []
};
for (var k = 0; k < current.posts.length; k++) {
var d = new Date(Date.parse(current.posts[k].date));
if (d.getDate() == day) {
count.keys[count.num++] = k;
}
}

if (count.num !== 0) {
var index = count.keys[0];
var cLink = $('<a>').attr('onclick', `pjax.loadUrl('${current.posts[index].link}')`).attr('title', current.posts[index].title).html(day++);
cDay.append(cLink);
} else {
cDay.html(day++);
}
} else {
cDay.addClass('cal-gray');
cDay.html(dayOfNextMonth++);
}

cWeek.append(cDay);
}

cMainPad.append(cWeek);
}

cBody.append(cWeekHead);
cBody.append(cFoot);
cBody.append(cMainPad);

$(instance).html(cHead);
$(instance).append(cBody);
}

return draw();
};

$.fn.aCalendar = function(Lang, oInit) {
return this.each(function() {
return aCalendar(Lang, oInit, $(this));
});
};

// plugin defaults
$.fn.aCalendar.defaults = {
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
dayOfWeekShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
postsMonthTip: 'Posts published in LMM yyyy',
titleFormat: 'yyyy LMM',
titleLinkFormat: '/archives/yyyy/MM/',
headArrows: {previous: '<span class="cal-prev"></span>', next: '<span class="cal-next"></span>'},
footArrows: {previous: '« ', next: ' »'},
weekOffset: 0,
single: true,
root: '/calendar/',
url: '/calendar.json'
};

}(jQuery));
$(document).ready(function () {
$("#calendar").aCalendar("zh-CN");
});

接下来在主题配置文件中引入这两个js和jquery

1
2
3
4
5
6
7
inject:
head:
- ...
bottom:
- <script type="text/javascript" src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script>
- <script type="text/javascript" src="/js/languages.js"></script>
- <script data-pjax type="text/javascript" src="/js/calendar.js"></script> #适配pjax

配置styl文件

添加 [blogRoot]\themes\butterfly\source\css\_layout\calendar.styl,编写:

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
#calendar
a
text-decoration none

.cal-head
position relative
height 20px
padding 8px 6px 2px 6px
margin-bottom 15px

.cal-prev,.cal-next
position absolute
top 9px
width 9px
height 10px
padding 3px 4px
border 1px solid transparent
color #333
outline 0

.cal-prev
left 8px
&:before
border-right 9px solid #333

.cal-next
right 8px
&:before
border-left 9px solid #333

.cal-prev:before,.cal-next:before
content ''
display block
width 0
height 0
border-top 5px solid transparent
border-bottom 5px solid transparent

.cal-title
width 120px
margin 0 auto
color #333
font bold 14px/18px Arial
text-align center
a
border 1px solid transparent
color #f76b61

.cal,
.cal th,
.cal td
border none

.cal
border-collapse collapse
border-spacing 0
table-layout fixed
width 100%
margin 0
th
background #00000000
color black
font-weight 900 !important
tbody
a
background-color #f76b61
color white
display block
font-weight 700
border 1px solid white
.cal-today
background-color #ffdfdd
color #f76b61
.cal-gray
color #ddd

.cal th,
.cal td
font-weight normal
line-height 2.5625
padding 0
text-align center

.cal-title a:hover,
.cal-prev:hover,
.cal-next:hover,
.cal .cal-foot:hover,
.cal .cal-foot:focus
cursor pointer
background-color transparent
cursor pointer
color #42d3d8

.cal tbody a:hover,
.cal tbody a:focus
background-color #ffdfdd
color #fff
cursor pointer

安装生成器

为了让js能够获取到文章列表,你需要安装一个生成器:

1
npm install --save git://github.com/howiefh/hexo-generator-calendar.git

然后配置插件,在hexo配置文件 _config.yml中追加:

1
2
3
calendar:
single: true
root: calendar/

然后 hexo cl&&hexo g -d一气呵成即可

2.天气插件

这个插件是使用和风天气的小组件进行修改的,效果如下:

1661149899740

我做了什么?

  1. 适配本站AcrylicUI
  2. 取舍部分组件保证效果
  3. 尺寸自适应而不是固定

教程

下面是教程:

申请和风天气小组件

你需要注册一个账号,国内平台不再赘述,进入以下链接注册即可:

然后进入控制台

创建一个插件,选项任意

1661161153544

1661161166909

1661161333671

生成代码后,复制代码的key部分。

PUG部分

添加 [blogRoot]\themes\butterfly\layout\includes\widget\card-weather.pug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.card-widget.card-weather(style='width:100%,height:270px')
.item-headline
i(class="fas fa-cloud-sun")
span="天气"
#he-plugin-standard
script.
WIDGET = {
"CONFIG": {
"layout": "2",
"width": 270,
"height": 270,
"background": "5",
"dataColor": "000000",
"key": "!{theme.aside.card_weather.key}"
}
}
script(src='https://widget.qweather.net/standard/static/js/he-standard-common.js?v=2.0')

然后修改 [blogRoot]\themes\butterfly\layout\includes\widget\index.pug

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
#aside-content.aside-content
//- post
if is_post()
...
else
!=partial('includes/widget/card_author', {}, {cache: true})
...
.sticky_layout
if showToc
include ./card_post_toc.pug
...
+ !=partial('includes/widget/card_weather', {}, {cache: true})
//- 如果不想在文章页显示可以不要
!=partial('includes/widget/card_ad', {}, {cache: true})

else
//- page
!=partial('includes/widget/card_author', {}, {cache: true})
...
.sticky_layout
if showToc
include ./card_post_toc.pug
...
+ !=partial('includes/widget/card_weather', {}, {cache: true})
...

主题配置文件

然后修改主题配置:

1
2
3
4
5
6
aside:
enable: true
...
card_weather:
enable: true
key: 1145141919810inm #你开始获取的key

css部分

然后添加一些css:

1
2
3
4
5
6
7
8
9
10
11
12
#he-plugin-standard{
width:100%!important;
margin-bottom:20px!important;
}
.wv-lt-location>a[data-v-4b9dcab4],.wv-lt-location>span[data-v-4b9dcab4],.wv-n-h-now-tmp>span[data-v-5f4c0628],.wv-n-h-now-txt>span[data-v-5f4c0628],.wv-n-h-now-rain>a[data-v-5f4c0628], .wv-n-h-now-rain>span[data-v-5f4c0628],.wv-f-forecast-date>a[data-v-66693262],.wv-f-a{
color:var(--font-color)!important;
font-family: 'HYTMR','Microsoft Yahei','PingFang SC','SimSun'!important;
font-size:14px
}
.wv-n-h-now-aqi-item {
display: none;
}

然后 hexo cl&&hexo g -d一气呵成即可