├── .gitignore ├── LICENSE ├── README.md ├── _config.yml ├── package-lock.json ├── package.json ├── scaffolds ├── draft.md ├── page.md └── post.md ├── source ├── _data │ ├── butterfly.yml │ └── link.yml ├── _posts │ └── hello-world.md ├── about │ └── index.md ├── bangumis │ └── index.md ├── books │ └── index.md ├── box │ ├── about │ │ └── index.html │ └── index.html ├── categories │ └── index.md ├── contact │ └── index.md ├── gallery │ └── index.md ├── home │ └── index.html ├── link │ └── index.md ├── movies │ └── index.md ├── music │ └── index.md ├── tags │ └── index.md └── talk │ └── index.md └── themes └── Butterfly ├── LICENSE ├── README.md ├── README_CN.md ├── _config.yml ├── languages ├── default.yml ├── en.yml ├── zh-CN.yml └── zh-TW.yml ├── layout ├── 404.pug ├── archive.pug ├── category.pug ├── flink.pug ├── includes │ ├── additional-js.pug │ ├── chat │ │ ├── chatra.pug │ │ ├── daovoice.pug │ │ ├── gitter.pug │ │ ├── index.pug │ │ └── tidio.pug │ ├── comments │ │ ├── disqus.pug │ │ ├── disqusjs.pug │ │ ├── facebook_comments.pug │ │ ├── gitalk.pug │ │ ├── index.pug │ │ ├── laibili.pug │ │ ├── livere.pug │ │ ├── utterances.pug │ │ └── valine.pug │ ├── footer.pug │ ├── head.pug │ ├── head │ │ ├── Open_Graph.pug │ │ ├── analytics.pug │ │ ├── aplayer.pug │ │ ├── comment.pug │ │ ├── config.pug │ │ ├── config_site.pug │ │ ├── darkmode.pug │ │ ├── dns_prefetch.pug │ │ ├── google_adsense.pug │ │ ├── noscript.pug │ │ ├── preconnect.pug │ │ ├── pwa.pug │ │ ├── site_verification.pug │ │ └── subtitle.pug │ ├── header │ │ ├── header.pug │ │ ├── index.pug │ │ ├── menu_item.pug │ │ ├── nav.pug │ │ ├── post-info.pug │ │ └── social.pug │ ├── layout.pug │ ├── loading │ │ ├── loading-js.pug │ │ └── loading.pug │ ├── math │ │ ├── index.pug │ │ ├── katex.pug │ │ ├── mathjax.pug │ │ └── mermaid.pug │ ├── mixins │ │ ├── article-sort.pug │ │ └── post-ui.pug │ ├── mobile-sidebar │ │ ├── index.pug │ │ └── mobile-menus.pug │ ├── pagination.pug │ ├── post │ │ ├── post-copyright.pug │ │ └── reward.pug │ ├── rightside.pug │ ├── search │ │ ├── algolia.pug │ │ ├── index.pug │ │ └── local-search.pug │ ├── share │ │ ├── add-this.pug │ │ ├── addtoany.pug │ │ ├── index.pug │ │ └── share-js.pug │ ├── sidebar.pug │ ├── third-party │ │ ├── canvas-nest.pug │ │ ├── canvas-ribbon-piao.pug │ │ ├── canvas-ribbon.pug │ │ └── pangu.pug │ └── widget │ │ ├── card_ad.pug │ │ ├── card_announcement.pug │ │ ├── card_archives.pug │ │ ├── card_author.pug │ │ ├── card_calendar.pug │ │ ├── card_categories.pug │ │ ├── card_map.pug │ │ ├── card_pixiv.pug │ │ ├── card_recent_post.pug │ │ ├── card_tags.pug │ │ ├── card_webinfo.pug │ │ └── index.pug ├── index.pug ├── page.pug ├── post.pug └── tag.pug ├── package.json ├── scripts ├── events │ ├── 404.js │ └── replace_config.js ├── filters │ ├── post_lazyload.js │ └── random_cover.js ├── helpers │ ├── aside_archives.js │ ├── aside_categories.js │ ├── page.js │ └── related_post.js └── tags │ ├── button.js │ ├── gallery.js │ ├── hide.js │ ├── mermaid.js │ ├── note.js │ └── tabs.js └── source ├── css ├── _global │ ├── function.styl │ └── index.styl ├── _highlight │ ├── diff.styl │ ├── highlight.styl │ └── theme.styl ├── _layout │ ├── 404.styl │ ├── aside.styl │ ├── calendar.styl │ ├── category.styl │ ├── chat.styl │ ├── comments.styl │ ├── flink.styl │ ├── footer.styl │ ├── head.styl │ ├── loadding.styl │ ├── mobile-sidebar.styl │ ├── page.styl │ ├── pagination.styl │ ├── post.styl │ ├── relatedposts.styl │ ├── reward.styl │ ├── rightside.styl │ ├── sidebar.styl │ └── third-party.styl ├── _mode │ ├── darkmode.styl │ └── readmode.styl ├── _search │ ├── algolia.styl │ ├── index.styl │ └── local-search.styl ├── _tags │ ├── button.styl │ ├── gallery.styl │ ├── hexo.styl │ ├── hide.styl │ ├── note.styl │ └── tabs.styl ├── _third-party │ └── normalize.min.css ├── index.styl └── var.styl ├── img ├── 404.jpg ├── algolia.svg ├── avatar.png ├── comment_bg.png ├── favicon.ico ├── favicon.png ├── friend_404.gif ├── icp.png ├── index.jpg ├── loading.gif ├── post.jpg └── post_loadding.svg └── js ├── calendar.js ├── languages.js ├── main.js ├── search ├── algolia.js └── local-search.js ├── third-party ├── ClickShowText.js ├── activate-power-mode.js ├── canvas-nest.js ├── canvas-ribbon.js ├── click_heart.js ├── fireworks.js └── piao.js ├── tw_cn.js └── utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: blog-lionkk 7 | subtitle: 'blog-lionkk' 8 | description: '不是只会写业务代码的前端攻城狮!' 9 | keywords: [Vue, 面试, CSDN, ES6, React, 前端] #网站的关键词 10 | author: 超逸 11 | language: zh-CN 12 | timezone: 'Asia/Shanghai' 13 | 14 | # URL 15 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 16 | url: http://yoursite.com 17 | root: / 18 | permalink: posts/:abbrlink/ 19 | permalink_defaults: 20 | pretty_urls: 21 | trailing_index: true # Set to false to remove trailing 'index.html' from permalinks 22 | trailing_html: true # Set to false to remove trailing '.html' from permalinks 23 | 24 | # Directory 25 | source_dir: source 26 | public_dir: public 27 | tag_dir: tags 28 | archive_dir: archives 29 | category_dir: categories 30 | code_dir: downloads/code 31 | i18n_dir: :lang 32 | skip_render: 33 | - 'home/*' 34 | - 'home/**' 35 | - 'box/*' 36 | - 'box/**' 37 | 38 | 39 | # Writing 40 | new_post_name: :title.md # File name of new posts 41 | default_layout: post 42 | titlecase: false # Transform title into titlecase 43 | external_link: 44 | enable: true # Open external links in new tab 45 | field: site # Apply to the whole site 46 | exclude: '' 47 | filename_case: 0 48 | render_drafts: false 49 | post_asset_folder: false 50 | relative_link: false 51 | future: true 52 | highlight: 53 | enable: true 54 | line_number: true 55 | auto_detect: false 56 | tab_replace: '' 57 | wrap: true 58 | hljs: false 59 | 60 | # Home page setting 61 | # path: Root path for your blogs index page. (default = '') 62 | # per_page: Posts displayed per page. (0 = disable pagination) 63 | # order_by: Posts order. (Order by date descending by default) 64 | index_generator: 65 | path: '' 66 | per_page: 10 67 | order_by: -date 68 | 69 | # Category & Tag 70 | default_category: uncategorized 71 | category_map: 72 | tag_map: 73 | 74 | # Metadata elements 75 | ## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta 76 | meta_generator: true 77 | 78 | # Date / Time format 79 | ## Hexo uses Moment.js to parse and display date 80 | ## You can customize the date format as defined in 81 | ## http://momentjs.com/docs/#/displaying/format/ 82 | date_format: YYYY-MM-DD 83 | time_format: HH:mm:ss 84 | ## Use post's date for updated date unless set in front-matter 85 | use_date_for_updated: false 86 | 87 | # Pagination 88 | ## Set per_page to 0 to disable pagination 89 | per_page: 10 90 | pagination_dir: page 91 | 92 | # Include / Exclude file(s) 93 | ## include:/exclude: options only apply to the 'source/' folder 94 | include: 95 | exclude: 96 | ignore: 97 | 98 | # Extensions 99 | ## Plugins: https://hexo.io/plugins/ 100 | ## Themes: https://hexo.io/themes/ 101 | theme: Butterfly 102 | 103 | # Deployment 104 | ## Docs: https://hexo.io/docs/deployment.html 105 | deploy: 106 | type: '' 107 | 108 | # bilibili番剧列表配置 109 | bangumi: 110 | enable: true 111 | vmid: '351534170' 112 | title: '追番列表' 113 | quote: '生命不息,追番不止!' 114 | show: 1 115 | loading: '/img/bangumi-loading.gif' 116 | 117 | # 添加卡通人物 118 | live2d: 119 | enable: true 120 | scriptFrom: local 121 | model: 122 | use: live2d-widget-model-haruto #模型选择 123 | display: 124 | position: right #模型位置 125 | width: 120 #模型宽度 126 | height: 260 #模型高度 127 | mobile: 128 | show: false #是否在手机端显示 129 | 130 | # 添加豆瓣 131 | # 豆瓣 132 | douban: 133 | user: 211251422 134 | builtin: true 135 | book: 136 | title: '好书推荐' 137 | quote: '读书好,好读书,读好书' 138 | movie: 139 | title: '电影' 140 | quote: '那些在电影院看过的电影' 141 | timeout: 10000 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "hexo generate", 7 | "clean": "hexo clean", 8 | "deploy": "hexo deploy", 9 | "server": "hexo server" 10 | }, 11 | "hexo": { 12 | "version": "4.2.0" 13 | }, 14 | "dependencies": { 15 | "hexo": "^5.4.1", 16 | "hexo-abbrlink": "^2.2.1", 17 | "hexo-bilibili-bangumi": "^1.8.2", 18 | "hexo-douban": "^2.1.0", 19 | "hexo-generator-archive": "^1.0.0", 20 | "hexo-generator-calendar": "git://github.com/howiefh/hexo-generator-calendar.git", 21 | "hexo-generator-category": "^1.0.0", 22 | "hexo-generator-index": "^1.0.0", 23 | "hexo-generator-tag": "^1.0.0", 24 | "hexo-helper-live2d": "^3.1.1", 25 | "hexo-renderer-ejs": "^2.0.0", 26 | "hexo-renderer-marked": "^6.0.0", 27 | "hexo-renderer-pug": "^3.0.0", 28 | "hexo-renderer-stylus": "^1.1.0", 29 | "hexo-server": "^1.0.0", 30 | "html-min": "0.0.4", 31 | "live2d-widget-model-haruto": "^1.0.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /source/_data/link.yml: -------------------------------------------------------------------------------- 1 | class: 2 | class_name: 酷酷のdalao们 3 | cdescr: 给dalao递零食✿✿ヽ(°▽°)ノ✿ 4 | link_list: 5 | 1: 6 | name: 超逸の技术博客 7 | link: https://chocolate.blog.csdn.net/ 8 | avatar: https://cdn.jsdelivr.net/gh/Chocolate1999/cdn/img/avatar.png 9 | descr: 学如逆水行舟,不进则退 10 | color: "#D2691E" 11 | custom: link_custom #动画样式 12 | time: 2s 13 | # 鼠标悬停旋转角度 14 | rotate: 360deg 15 | 16 | class2: 17 | class_name: 小伙伴们 18 | cdescr: 给小伙伴们递茶✿✿ヽ(°▽°)ノ✿ 19 | link_list: 20 | 1: 21 | name: 超逸の技术博客 22 | link: https://chocolate.blog.csdn.net/ 23 | avatar: https://cdn.jsdelivr.net/gh/Chocolate1999/cdn/img/avatar.png 24 | descr: 学如逆水行舟,不进则退 25 | 26 | class3: 27 | class_name: 链接失效 28 | cdescr: 怎么Server Down了呢?赶紧回来吧ヽ(。>д<)p 29 | link_list: 30 | 1: 31 | name: 未知1 32 | link: https://chocolate.blog.csdn.net/ 33 | avatar: https://cdn.jsdelivr.net/gh/Chocolate1999/cdn/img/avatar1.png 34 | descr: test 35 | 36 | class4: 37 | class_name: 友链样式(可选) 38 | cdescr: 小伙伴可以选择或提供自己的友链风格嗷~(未选择就根据您的博客主题配色加边框) 39 | link_list: 40 | 1: 41 | name: 程序媛(默认) 42 | link: https://chocolate.blog.csdn.net/ 43 | avatar: https://cdn.jsdelivr.net/gh/Chocolate1999/cdn/img/avatar.png 44 | descr: 粉色呼吸灯 45 | color: "#ff9999" 46 | custom: link_custom #动画样式 47 | time: 2s 48 | # 鼠标悬停旋转角度 49 | rotate: 360deg 50 | 2: 51 | name: 程序员(默认) 52 | link: https://chocolate.blog.csdn.net/ 53 | avatar: https://cdn.jsdelivr.net/gh/Chocolate1999/cdn/img/avatar.png 54 | descr: 蓝色呼吸灯 55 | color: "#0078e7" 56 | custom: link_custom #动画样式 57 | time: 2s 58 | # 鼠标悬停旋转角度 59 | rotate: 360deg 60 | 3: 61 | name: 炫彩样式 62 | link: https://chocolate.blog.csdn.net/ 63 | avatar: https://cdn.jsdelivr.net/gh/Chocolate1999/cdn/img/avatar.png 64 | descr: 炫彩呼吸灯 65 | color: "#0078e7" 66 | custom: link_custom1 #动画样式 67 | time: 2s 68 | # 鼠标悬停旋转角度 69 | rotate: 360deg -------------------------------------------------------------------------------- /source/_posts/hello-world.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | tags: 4 | - 总结 5 | - blog 6 | categories: 7 | - blog 8 | keywords: "hello,总结" 9 | cover: https://cdn.jsdelivr.net/gh/HCLonely/hclonely.github.io/img/Butterfly/006.webp 10 | toc: True 11 | abbrlink: 520520 12 | --- 13 | Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). 14 | 15 | ## Quick Start 16 | 17 | ### Create a new post 18 | 19 | ``` bash 20 | $ hexo new "My New Post" 21 | ``` 22 | 23 | More info: [Writing](https://hexo.io/docs/writing.html) 24 | 25 | ### Run server 26 | 27 | ``` bash 28 | $ hexo server 29 | ``` 30 | 31 | More info: [Server](https://hexo.io/docs/server.html) 32 | 33 | ### Generate static files 34 | 35 | ``` bash 36 | $ hexo generate 37 | ``` 38 | 39 | More info: [Generating](https://hexo.io/docs/generating.html) 40 | 41 | ### Deploy to remote sites 42 | 43 | ``` bash 44 | $ hexo deploy 45 | ``` 46 | 47 | More info: [Deployment](https://hexo.io/docs/one-command-deployment.html) 48 | -------------------------------------------------------------------------------- /source/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于本站 3 | date: 2020-04-19 12:58:56 4 | type: "about" 5 | --- 6 | 7 | ## 神奇の沟通 8 | 9 | - 沟通是 **传递** 沟通是 **交流** 10 | - 沟通是 **分享** 沟通是 **智慧** 11 | - 沟通是 **友谊** 沟通是 **力量** 12 | 13 | " **认识自我、超越自我** " 是沟通的最高境界 14 | 15 | - 当你在项目中感觉所要学习的人和事越来越多时,说明你在 **成长** 。 16 | - 当你感觉要责怪的人和事越来越少时,说明你在 **成熟** 。 17 | - 当你在项目中不断获得了友谊和朋友时,说明你将取得项目的 **成功** 。 18 | 19 | 20 | ## 联系我 21 | CSDN:https://chocolate.blog.csdn.net/(CSDN认证博客专家) 22 | 23 | 微信公众号:小狮子前端Vue 24 | 25 | 一个不是只会写业务代码的前端攻城狮会带给你怎样的体会呢? 26 | 27 | 座右铭:学如逆水行舟,不进则退 -------------------------------------------------------------------------------- /source/bangumis/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 番剧列表 3 | date: 2020-04-20 09:39:20 4 | type: "bangumis" 5 | --- 6 | -------------------------------------------------------------------------------- /source/books/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 书单 3 | date: 2020-04-19 12:58:56 4 | type: "books" 5 | --- 6 | -------------------------------------------------------------------------------- /source/categories/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 分类 3 | date: 2020-04-19 12:59:34 4 | type: "categories" 5 | --- 6 | -------------------------------------------------------------------------------- /source/contact/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 留言板 3 | date: 2020-04-23 07:39:34 4 | type: "contact" 5 | --- 6 | -------------------------------------------------------------------------------- /source/gallery/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 相册集 3 | date: 2020-04-21 18:44:23 4 | description: 5 | top_img: 6 | --- 7 | 8 | {% gallery %} 9 | ![](https://cdn.jsdelivr.net/gh/HCLonely/hclonely.github.io/img/Butterfly/013.webp) 10 | ![](https://cdn.jsdelivr.net/gh/HCLonely/hclonely.github.io/img/Butterfly/023.webp) 11 | ![](https://cdn.jsdelivr.net/gh/HCLonely/hclonely.github.io/img/Butterfly/033.webp) 12 | ![](https://cdn.jsdelivr.net/gh/HCLonely/hclonely.github.io/img/Butterfly/003.webp) 13 | 14 | {% endgallery %} -------------------------------------------------------------------------------- /source/link/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 友情链接 3 | date: 2020-04-19 13:00:10 4 | type: "link" 5 | --- 6 | -------------------------------------------------------------------------------- /source/movies/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 电影 3 | date: 2020-04-19 12:58:56 4 | type: "movies" 5 | --- 6 | -------------------------------------------------------------------------------- /source/music/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Music 3 | date: 2020-04-23 12:58:56 4 | type: 'music' 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /source/tags/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 标签 3 | date: 2020-04-19 12:58:56 4 | type: "tags" 5 | --- 6 | -------------------------------------------------------------------------------- /source/talk/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 说说 3 | date: 2020-04-23 07:47:23 4 | type: "talk" 5 | --- -------------------------------------------------------------------------------- /themes/Butterfly/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /themes/Butterfly/README.md: -------------------------------------------------------------------------------- 1 | # hexo-theme-butterfly 2 | 3 | Version 4 | Author 5 | Hexo 6 | node.js 7 | 8 | Demo: 👍 [Butterfly](https://demo.jerryc.me/) || 🤞 [JerryC](https://jerryc.me/) 9 | 10 | Based on [hexo-theme-melody](https://github.com/Molunerfinn/hexo-theme-melody) theme. 11 | 12 | ## Installation 13 | 14 | Stable branch [recommend]: 15 | 16 | ``` 17 | git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 18 | ``` 19 | 20 | Dev branch: 21 | 22 | ``` 23 | git clone -b dev https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 24 | ``` 25 | 26 | ## Configuration 27 | 28 | Set theme in the hexo work folder's root config file `_config.yml`: 29 | 30 | > theme: butterfly 31 | 32 | If you don't have pug & stylus renderer, try this: 33 | 34 | > npm install hexo-renderer-pug hexo-renderer-stylus 35 | 36 | ## Documentation 37 | 38 | Find in [Butterfly Docs](https://demo.jerryc.me/posts/21cfbf15/). it supports `zh-TW` and `zh-CN` 39 | 40 | You can also join the Chat Group. 41 | 42 | [💬 Join QQ Group [recommend]](https://jq.qq.com/?_wv=1027&k=5KI3Jqb) 43 | 44 | [💬 Join Telegram Group](https://t.me/hexo_butterfly) 45 | 46 | 47 | 48 | ## Screenshots 49 | 50 | ![image](https://user-images.githubusercontent.com/16351105/58887365-1272f780-8718-11e9-9329-3292c6ba20d4.png) 51 | 52 | ![](https://user-images.githubusercontent.com/16351105/58887457-3cc4b500-8718-11e9-9417-2bdea603c92e.png) 53 | 54 | ![](https://user-images.githubusercontent.com/16351105/69338594-7d03f980-0c9e-11ea-8b64-7f165e6508e2.png) -------------------------------------------------------------------------------- /themes/Butterfly/README_CN.md: -------------------------------------------------------------------------------- 1 | # hexo-theme-butterfly 2 | 3 | Version 4 | Author 5 | Hexo 6 | node.js 7 | 8 | Demo: 👍 [Butterfly](https://demo.jerryc.me/) || 🤞 [JerryC](https://jerryc.me/) 9 | 10 | 一款基於[hexo-theme-melody](https://github.com/Molunerfinn/hexo-theme-melody)修改的主題 11 | 12 | ## 安裝 13 | 14 | 在你的博客根目錄裡安裝穩定版【推薦】 15 | 16 | ``` 17 | git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 18 | ``` 19 | 20 | 如果想要安裝比較新的dev分支,可以 21 | 22 | ``` 23 | git clone -b dev https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 24 | ``` 25 | 26 | ## 應用主題 27 | 修改hexo配置文件`_config.yml`,把主題改為`Butterfly` 28 | 29 | ``` 30 | theme: butterfly 31 | ``` 32 | 33 | >如果你沒有pug以及stylus的渲染器,請下載安裝: npm install hexo-renderer-pug hexo-renderer-stylus --save or yarn add hexo-renderer-pug hexo-renderer-stylus 34 | 35 | ## 文檔 36 | 37 | 可查看[Butterfly Docs](https://demo.jerryc.me/posts/21cfbf15/) 38 | 39 | 你也可以加入群組 40 | 41 | [ 💬 QQ群 [推薦]](https://jq.qq.com/?_wv=1027&k=5KI3Jqb) 42 | 43 | [ 💬 Telegram群](https://t.me/hexo_butterfly) 44 | 45 | ## 截圖 46 | 47 | ![image](https://user-images.githubusercontent.com/16351105/58887365-1272f780-8718-11e9-9329-3292c6ba20d4.png) 48 | ![image](https://user-images.githubusercontent.com/16351105/58887457-3cc4b500-8718-11e9-9417-2bdea603c92e.png) 49 | 50 | ![](https://user-images.githubusercontent.com/16351105/69338594-7d03f980-0c9e-11ea-8b64-7f165e6508e2.png) -------------------------------------------------------------------------------- /themes/Butterfly/languages/default.yml: -------------------------------------------------------------------------------- 1 | sidebar: 2 | catalog: Catalog 3 | have_read: You've read 4 | 5 | footer: 6 | driven: Driven 7 | theme: Theme 8 | 9 | copy: 10 | success: Copy successfully 11 | error: Copy error 12 | noSupport: The browser does not support 13 | 14 | page: 15 | articles: Articles 16 | tag: Tag 17 | category: Category 18 | archives: Archives 19 | 20 | sticky: Sticky 21 | no_title: No title 22 | 23 | post: 24 | created: Created 25 | updated: Updated 26 | wordcount: Word count 27 | min2read: 'Reading time: %s min' 28 | page_pv: Post View 29 | comments: Comments 30 | copyright: 31 | author: Author 32 | link: Link 33 | copyright_notice: Copyright Notice 34 | copyright_content: 'All articles in this blog are licensed under %s unless stating additionally.' 35 | recommend: Related Articles 36 | 37 | search: Search 38 | algolia_search: 39 | input_placeholder: Search for Posts 40 | hits_empty: "We didn't find any results for the search: ${query}." 41 | hits_stats: '${hits} results found in ${time} ms' 42 | 43 | local_search: 44 | label: Local search 45 | input_placeholder: Search for Posts 46 | hits_empty: "We didn't find any results for the search: ${query}" 47 | powered_by: Powered by 48 | 49 | pagination: 50 | prev: Previous Post 51 | next: Next Post 52 | 53 | comment: Comment 54 | 55 | aside: 56 | articles: Articles 57 | tags: Tags 58 | categories: Categories 59 | card_announcement: Announcement 60 | card_categories: Categories 61 | card_tags: Tags 62 | card_archives: Archives 63 | card_recent_post: Recent Post 64 | card_bookmark: Bookmark 65 | card_webinfo: 66 | headline: Info 67 | article_name: Article 68 | runtime_name: Run time 69 | site_wordcount: Total Count 70 | site_uv_name: UV 71 | site_pv_name: PV 72 | more_button: More 73 | 74 | donate: Donate 75 | share: Share 76 | bookmark: 77 | title: Bookmark 78 | 79 | rightside: 80 | readmode_title: Read Mode 81 | font_plus_title: Increase Font Size 82 | font_minus_title: Decrease Font Size 83 | translate_title: Switch Between Traditional Chinese And Simplified Chinese 84 | night_mode_title: Switch Between Light And Dark Mode 85 | back_to_top: Back To Top 86 | toc: Table Of Contents 87 | scroll_to_comment: Scroll To Comments 88 | setting: Setting 89 | 90 | runtime_unit: days 91 | 92 | copy_copyright: 93 | author: Author 94 | link: Link 95 | source: Source 96 | info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source. 97 | 98 | Snackbar: 99 | bookmark: 100 | message_prev: Press 101 | message_next: to bookmark this page 102 | chs_to_cht: Traditional Chinese Activated Manually 103 | cht_to_chs: Simplified Chinese Activated Manually 104 | day_to_night: Dark Mode Activated Manually 105 | night_to_day: Light Mode Activated Manually 106 | 107 | loading: Loading... 108 | 109 | error404: 110 | error_title: Page not found 111 | back_button: Go back home 112 | -------------------------------------------------------------------------------- /themes/Butterfly/languages/en.yml: -------------------------------------------------------------------------------- 1 | sidebar: 2 | catalog: Catalog 3 | have_read: You've read 4 | 5 | footer: 6 | driven: Driven 7 | theme: Theme 8 | 9 | copy: 10 | success: Copy successfully 11 | error: Copy error 12 | noSupport: The browser does not support 13 | 14 | page: 15 | articles: Articles 16 | tag: Tag 17 | category: Category 18 | archives: Archives 19 | 20 | sticky: Sticky 21 | no_title: No title 22 | 23 | post: 24 | created: Created 25 | updated: Updated 26 | wordcount: Word count 27 | min2read: 'Reading time: %s min' 28 | page_pv: Post View 29 | comments: Comments 30 | copyright: 31 | author: Author 32 | link: Link 33 | copyright_notice: Copyright Notice 34 | copyright_content: 'All articles in this blog are licensed under %s unless stating additionally.' 35 | recommend: Related Articles 36 | 37 | search: Search 38 | algolia_search: 39 | input_placeholder: Search for Posts 40 | hits_empty: "We didn't find any results for the search: ${query}." 41 | hits_stats: '${hits} results found in ${time} ms' 42 | 43 | local_search: 44 | label: Local search 45 | input_placeholder: Search for Posts 46 | hits_empty: "We didn't find any results for the search: ${query}" 47 | powered_by: Powered by 48 | 49 | pagination: 50 | prev: Previous Post 51 | next: Next Post 52 | 53 | comment: Comment 54 | 55 | aside: 56 | articles: Articles 57 | tags: Tags 58 | categories: Categories 59 | card_announcement: Announcement 60 | card_categories: Categories 61 | card_tags: Tags 62 | card_archives: Archives 63 | card_recent_post: Recent Post 64 | card_bookmark: Bookmark 65 | card_webinfo: 66 | headline: Info 67 | article_name: Article 68 | runtime_name: Run time 69 | site_wordcount: Total Count 70 | site_uv_name: UV 71 | site_pv_name: PV 72 | more_button: More 73 | 74 | donate: Donate 75 | share: Share 76 | bookmark: 77 | title: Bookmark 78 | 79 | rightside: 80 | readmode_title: Read Mode 81 | font_plus_title: Increase Font Size 82 | font_minus_title: Decrease Font Size 83 | translate_title: Switch Between Traditional Chinese And Simplified Chinese 84 | night_mode_title: Switch Between Light And Dark Mode 85 | back_to_top: Back To Top 86 | toc: Table Of Contents 87 | scroll_to_comment: Scroll To Comments 88 | setting: Setting 89 | 90 | runtime_unit: days 91 | 92 | copy_copyright: 93 | author: Author 94 | link: Link 95 | source: Source 96 | info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source. 97 | 98 | Snackbar: 99 | bookmark: 100 | message_prev: Press 101 | message_next: to bookmark this page 102 | chs_to_cht: Traditional Chinese Activated Manually 103 | cht_to_chs: Simplified Chinese Activated Manually 104 | day_to_night: Dark Mode Activated Manually 105 | night_to_day: Light Mode Activated Manually 106 | 107 | loading: Loading... 108 | 109 | error404: 110 | error_title: Page not found 111 | back_button: Go back home 112 | -------------------------------------------------------------------------------- /themes/Butterfly/languages/zh-CN.yml: -------------------------------------------------------------------------------- 1 | sidebar: 2 | catalog: 目录 3 | have_read: 你已经读了 4 | 5 | footer: 6 | driven: 驱动 7 | theme: 主题 8 | 9 | copy: 10 | success: 复制成功 11 | error: 复制错误 12 | noSupport: 浏览器不支持 13 | 14 | page: 15 | articles: 文章总览 16 | tag: 标签 17 | category: 分类 18 | archives: 归档 19 | 20 | sticky: 置顶 21 | no_title: 无题 22 | 23 | post: 24 | created: 发表于 25 | updated: 更新于 26 | wordcount: 字数总计 27 | min2read: '阅读时长: %s 分钟' 28 | page_pv: 阅读量 29 | comments: 评论数 30 | copyright: 31 | author: 文章作者 32 | link: 文章链接 33 | copyright_notice: 版权声明 34 | copyright_content: '本博客所有文章除特别声明外,均采用 35 | %s 许可协议。转载请注明来自 %s!' 36 | recommend: 相关推荐 37 | 38 | search: 搜索 39 | algolia_search: 40 | input_placeholder: 搜索文章 41 | hits_empty: '找不到您查询的内容:${query}' 42 | hits_stats: '找到 ${hits} 条结果,用时 ${time} 毫秒' 43 | 44 | local_search: 45 | label: 本地搜索 46 | input_placeholder: 搜索文章 47 | hits_empty: '找不到您查询的内容:${query}' 48 | powered: '提供支持' 49 | by: 由 50 | 51 | pagination: 52 | prev: 上一篇 53 | next: 下一篇 54 | 55 | comment: 评论 56 | 57 | aside: 58 | articles: 文章 59 | tags: 标签 60 | categories: 分类 61 | card_announcement: 公告 62 | card_categories: 分类 63 | card_tags: 标签 64 | card_archives: 归档 65 | card_pixiv: Pixiv日榜Top50 66 | card_calendar: 写作日历 67 | card_map: 访客地图 68 | card_recent_post: 最新文章 69 | card_bookmark: 加入书签 70 | card_webinfo: 71 | headline: 网站资讯 72 | article_name: 文章数目 73 | runtime_name: 已运行时间 74 | site_wordcount: 本站总字数 75 | site_uv_name: 本站访客数 76 | site_pv_name: 本站总访问量 77 | more_button: 查看更多 78 | 79 | donate: 打赏 80 | share: 分享 81 | bookmark: 82 | title: 添加书签 83 | 84 | rightside: 85 | readmode_title: 阅读模式 86 | font_plus_title: 放大字体 87 | font_minus_title: 缩小字体 88 | translate_title: 简繁转换 89 | night_mode_title: 浅色和深色模式转换 90 | back_to_top: 回到顶部 91 | toc: 目录 92 | scroll_to_comment: 直达评论 93 | setting: 设置 94 | 95 | runtime_unit: 天 96 | 97 | copy_copyright: 98 | author: 作者 99 | link: 链接 100 | source: 来源 101 | info: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 102 | 103 | Snackbar: 104 | bookmark: 105 | message_prev: 按 106 | message_next: 键将本页加入书签 107 | chs_to_cht: 你已切换为繁体 108 | cht_to_chs: 你已切换为简体 109 | day_to_night: 你已切换为深色模式 110 | night_to_day: 你已切换为浅色模式 111 | 112 | error_title: 页面没有找到 113 | loading: 加载中... 114 | 115 | error404: 116 | error_title: 页面没有找到 117 | back_button: 回到主页 118 | -------------------------------------------------------------------------------- /themes/Butterfly/languages/zh-TW.yml: -------------------------------------------------------------------------------- 1 | sidebar: 2 | catalog: 目錄 3 | have_read: 你已經讀了 4 | 5 | footer: 6 | driven: Power by 7 | theme: Theme 8 | 9 | copy: 10 | success: 複製成功 11 | error: 複製錯誤 12 | noSupport: 瀏覽器不支援 13 | 14 | page: 15 | articles: 文章總覽 16 | tag: 標籤 17 | category: 分類 18 | archives: 歸檔 19 | 20 | sticky: 置頂 21 | no_title: 無題 22 | 23 | post: 24 | created: 發表於 25 | updated: 更新於 26 | wordcount: 字數總計 27 | min2read: '閱讀時長: %s 分鐘' 28 | page_pv: 閱讀量 29 | comments: 評論數 30 | copyright: 31 | author: 文章作者 32 | link: 文章連結 33 | copyright_notice: 版權聲明 34 | copyright_content: '本部落格所有文章除特別聲明外,均採用 35 | %s 許可協議。轉載請註明來自 %s!' 36 | recommend: 相關推薦 37 | 38 | search: 搜尋 39 | algolia_search: 40 | input_placeholder: 搜尋文章 41 | hits_empty: '找不到您查詢的內容:${query}' 42 | hits_stats: '找到 ${hits} 條結果,用時 ${time} 毫秒' 43 | 44 | local_search: 45 | label: 本地搜尋 46 | input_placeholder: 搜尋文章 47 | hits_empty: '找不到您查詢的內容:${query}' 48 | powered: '提供支援' 49 | by: 由 50 | 51 | pagination: 52 | prev: 上一篇 53 | next: 下一篇 54 | 55 | comment: 評論 56 | 57 | aside: 58 | articles: 文章 59 | tags: 標籤 60 | categories: 分類 61 | card_announcement: 公告 62 | card_categories: 分類 63 | card_tags: 標籤 64 | card_archives: 歸檔 65 | card_recent_post: 最新文章 66 | card_bookmark: 加入書籤 67 | card_webinfo: 68 | headline: 網站資訊 69 | article_name: 文章數目 70 | runtime_name: 已執行時間 71 | site_wordcount: 本站總字數 72 | site_uv_name: 本站訪客數 73 | site_pv_name: 本站總訪問量 74 | more_button: 檢視更多 75 | 76 | donate: 打賞 77 | share: 分享 78 | bookmark: 79 | title: 新增書籤 80 | 81 | rightside: 82 | readmode_title: 閱讀模式 83 | font_plus_title: 放大字型 84 | font_minus_title: 縮小字型 85 | translate_title: 簡繁轉換 86 | night_mode_title: 淺色和深色模式轉換 87 | back_to_top: 回到頂部 88 | toc: 目錄 89 | scroll_to_comment: 直達評論 90 | setting: 設定 91 | 92 | runtime_unit: 天 93 | 94 | copy_copyright: 95 | author: 作者 96 | link: 連結 97 | source: 來源 98 | info: 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 99 | 100 | Snackbar: 101 | bookmark: 102 | message_prev: 按 103 | message_next: 鍵將本頁加入書籤 104 | chs_to_cht: 你已切換為繁體 105 | cht_to_chs: 你已切換為簡體 106 | day_to_night: 你已切換為深色模式 107 | night_to_day: 你已切換為淺色模式 108 | 109 | loading: 載入中... 110 | 111 | error404: 112 | error_title: 頁面沒有找到 113 | back_button: 回到主頁 114 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/404.pug: -------------------------------------------------------------------------------- 1 | - var top_img = theme.error_404.background || theme.default_top_img 2 | - var bg_img = `background-image: url(${url_for(top_img)})` 3 | 4 | doctype html 5 | html(lang=config.language data-theme=theme.display_mode) 6 | head 7 | include includes/head.pug 8 | body 9 | if theme.preloader 10 | !=partial('includes/loading/loading', {}, {cache:theme.fragment_cache}) 11 | 12 | if theme.fireworks && theme.fireworks.enable 13 | canvas.fireworks 14 | 15 | if theme.background 16 | - var is_photo = theme.background.startsWith('url') ? 'photo':'color' 17 | #web_bg(data-type=is_photo) 18 | 19 | #error-wrap 20 | .error-content 21 | .error-img(style=bg_img) 22 | .error-info 23 | h1.error_title= '404' 24 | .error_subtitle= theme.error_404.subtitle 25 | a.button--animated(href=url_for(config.root)) 26 | i.fas.fa-rocket 27 | = _p('error404.back_button') 28 | 29 | !=partial('includes/search/index', {}, {cache:theme.fragment_cache}) 30 | include includes/additional-js.pug 31 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/archive.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | include ./includes/mixins/article-sort.pug 5 | #archive 6 | .article-sort-title= _p('page.articles') + ' - ' + site.posts.length 7 | +articleSort(page.posts) 8 | include includes/pagination.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/category.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | if theme.category_ui == 'index' 5 | include ./includes/mixins/post-ui.pug 6 | #recent-posts.recent-posts.category_ui 7 | +postUI 8 | include includes/pagination.pug 9 | else 10 | include ./includes/mixins/article-sort.pug 11 | #category 12 | .article-sort-title= _p('page.category') + ' - ' + page.category 13 | +articleSort(page.posts) 14 | include includes/pagination.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/flink.pug: -------------------------------------------------------------------------------- 1 | #page 2 | .flink#article-container 3 | if site.data.link 4 | each i in site.data.link 5 | if i.class_name 6 | h2!= i.class_name 7 | h4= i.cdescr 8 | if i.class_desc 9 | .flink-desc!=i.class_desc 10 | .flink-list 11 | each item in i.link_list 12 | .flink-list-item(style= item.color ? `--primary-color:${item.color};border-width:${item.width};border-style:${item.style};animation: ${item.custom} ${item.time} infinite alternate; background:${item.background}` : 'border-width:0px;border-style:solid;animation: link_custom 0s infinite alternate;background:0') 13 | a(href=url_for(item.link) title=item.name target="_blank" rel=item.remove ? "external nofollow" : "" style=item.namecolor ? `--namecolor:${item.namecolor}` : '') 14 | if theme.lazyload.enable 15 | img(data-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name ,style=item.rotate ? `--primary-rotate:${item.rotate};--autotime:${item.autotime};` : '--primary-rotate:0deg' class=item.autorotate ? `${item.autorotate}` : '') 16 | else 17 | img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name ) 18 | .flink-item-name= item.name 19 | .flink-item-desc= item.descr 20 | != page.content 21 | p(style="font-size:14px;font-weight:bold")= theme.PS 22 | hr 23 | h2= theme.require_headline 24 | ul 25 | li= theme.requirement1 26 | li= theme.requirement2 27 | li= theme.requirement3 28 | li= theme.requirement4 29 | li= theme.requirement5 30 | li= theme.requirement6 31 | hr 32 | h2= theme.myInfo 33 | ul 34 | li= theme.info1 35 | li= theme.info2 36 | li= theme.info3 37 | li= theme.info4 38 | if page.comments !== false 39 | include includes/comments/index.pug 40 | 41 | 42 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/additional-js.pug: -------------------------------------------------------------------------------- 1 | script(src=url_for(theme.CDN.jquery)) 2 | script(src=url_for(theme.CDN.utils)) 3 | script(src=url_for(theme.CDN.main)) 4 | 5 | if theme.translate && theme.translate.enable 6 | script(src=url_for(theme.CDN.translate)) 7 | 8 | if theme.medium_zoom 9 | script(src=url_for(theme.CDN.medium_zoom)) 10 | 11 | if theme.fancybox 12 | script(src=url_for(theme.CDN.fancybox)) 13 | 14 | include ./math/index.pug 15 | 16 | if theme.fireworks && theme.fireworks.enable 17 | script(src=url_for(theme.CDN.anime)) 18 | script(src=url_for(theme.CDN.fireworks)) 19 | 20 | if (theme.snackbar && theme.snackbar.enable) 21 | script(src=url_for(theme.CDN.snackbar)) 22 | 23 | if (theme.canvas_ribbon && theme.canvas_ribbon.enable) 24 | include ./third-party/canvas-ribbon.pug 25 | 26 | if (theme.canvas_ribbon_piao && theme.canvas_ribbon_piao.enable) 27 | include ./third-party/canvas-ribbon-piao.pug 28 | 29 | if (theme.canvas_nest && theme.canvas_nest.enable) 30 | include ./third-party/canvas-nest.pug 31 | 32 | if theme.activate_power_mode.enable 33 | script(src=url_for(theme.CDN.activate_power_mode)) 34 | script. 35 | POWERMODE.colorful = #{theme.activate_power_mode.colorful}; 36 | POWERMODE.shake = #{theme.activate_power_mode.shake}; 37 | document.body.addEventListener('input', POWERMODE); 38 | 39 | if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv 40 | script(async src=url_for(theme.CDN.busuanzi)) 41 | 42 | if theme.instantpage 43 | script(src=url_for(theme.CDN.instantpage) type="module" defer) 44 | 45 | if theme.lazyload.enable 46 | script(src=url_for(theme.CDN.lazyload) async) 47 | 48 | //- 鼠標特效 49 | if theme.click_heart 50 | script(src=url_for(theme.CDN.click_heart)) 51 | 52 | if theme.ClickShowText && theme.ClickShowText.enable 53 | script(src=url_for(theme.CDN.ClickShowText)) 54 | 55 | if theme.pangu && theme.pangu.enable 56 | include ./third-party/pangu.pug 57 | 58 | //- search 59 | if theme.algolia_search && theme.algolia_search.enable 60 | script(src=url_for(theme.CDN.algolia_js)) 61 | else if theme.local_search && theme.local_search.enable 62 | script(src=url_for(theme.CDN.local_search)) 63 | 64 | //- mermaid 65 | if theme.mermaid.enable 66 | include ./math/mermaid.pug 67 | 68 | if is_home() 69 | include ./head/subtitle.pug 70 | 71 | !=fragment_cache('injectBottom', function(){return injectHtml(theme.inject.bottom)}) 72 | 73 | if theme.preloader 74 | !=partial('includes/loading/loading-js', {}, {cache:theme.fragment_cache}) 75 | 76 | !=partial('includes/chat/index', {}, {cache:theme.fragment_cache}) 77 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/chat/chatra.pug: -------------------------------------------------------------------------------- 1 | //- https://chatra.io/help/api/ 2 | script. 3 | (function(d, w, c) { 4 | w.ChatraID = '#{theme.chatra.id}'; 5 | var s = d.createElement('script'); 6 | w[c] = w[c] || function() { 7 | (w[c].q = w[c].q || []).push(arguments); 8 | }; 9 | s.async = true; 10 | s.src = 'https://call.chatra.io/chatra.js'; 11 | if (d.head) d.head.appendChild(s); 12 | })(document, window, 'Chatra'); 13 | 14 | if (!{theme.chat_btn}) { 15 | var chatBtn = document.getElementById("chat_btn") 16 | chatBtn.addEventListener("click", function(){ 17 | Chatra('openChat') 18 | }); 19 | } else { 20 | if (!{theme.chat_hide_show}) { 21 | function chatBtnHide () { 22 | Chatra('hide') 23 | } 24 | function chatBtnShow () { 25 | Chatra('show') 26 | } 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/chat/daovoice.pug: -------------------------------------------------------------------------------- 1 | //- https://guide.daocloud.io/daovoice/javascript-api-5869833.html 2 | script. 3 | (function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/!{theme.daovoice.app_id}.js","daovoice") 4 | 5 | script. 6 | var isChatBtn = !{theme.chat_btn} 7 | daovoice('init', { 8 | app_id: '!{theme.daovoice.app_id}',},{ 9 | launcher: { 10 | disableLauncherIcon: isChatBtn // 悬浮 ICON 是否显示 11 | }, 12 | }); 13 | daovoice('update'); 14 | 15 | if (isChatBtn) { 16 | var chatBtn = document.getElementById("chat_btn") 17 | chatBtn.addEventListener("click", function(){ 18 | daovoice('show') 19 | }); 20 | } else { 21 | if (!{theme.chat_hide_show}) { 22 | function chatBtnHide () { 23 | daovoice('update', {},{ 24 | launcher: { 25 | disableLauncherIcon: true // 悬浮 ICON 是否显示 26 | }, 27 | }); 28 | } 29 | function chatBtnShow () { 30 | daovoice('update', {},{ 31 | launcher: { 32 | disableLauncherIcon: false // 悬浮 ICON 是否显示 33 | }, 34 | }); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/chat/gitter.pug: -------------------------------------------------------------------------------- 1 | //- https://sidecar.gitter.im/ 2 | script. 3 | var isChatBtn = !{theme.chat_btn} 4 | 5 | if (isChatBtn) { 6 | ((window.gitter = {}).chat = {}).options = { 7 | room: '#{theme.gitter.room}', 8 | activationElement: '#chat_btn' 9 | }; 10 | } else { 11 | ((window.gitter = {}).chat = {}).options = { 12 | room: '#{theme.gitter.room}', 13 | }; 14 | 15 | if (!{theme.chat_hide_show}) { 16 | var gitterBtn = document.getElementsByClassName('gitter-open-chat-button') 17 | 18 | function chatBtnHide () { 19 | gitterBtn[0].style.display= 'none' 20 | } 21 | 22 | function chatBtnShow () { 23 | gitterBtn[0].style.display= 'block' 24 | } 25 | } 26 | } 27 | 28 | script(src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/chat/index.pug: -------------------------------------------------------------------------------- 1 | if theme.chatra && theme.chatra.enable 2 | include ./chatra.pug 3 | else if theme.tidio && theme.tidio.enable 4 | include ./tidio.pug 5 | else if theme.daovoice && theme.daovoice.enable 6 | include ./daovoice.pug 7 | else if theme.gitter && theme.gitter.enable 8 | include ./gitter.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/chat/tidio.pug: -------------------------------------------------------------------------------- 1 | script(src=`//code.tidio.co/${theme.tidio.public_key}.js` async) 2 | 3 | if theme.chat_btn 4 | script. 5 | (function() { 6 | function onTidioChatApiReady() { 7 | window.tidioChatApi.hide(); 8 | window.tidioChatApi.on("close", function() { 9 | window.tidioChatApi.hide(); 10 | }); 11 | } 12 | if (window.tidioChatApi) { 13 | window.tidioChatApi.on("ready", onTidioChatApiReady); 14 | } else { 15 | document.addEventListener("tidioChat-ready", onTidioChatApiReady); 16 | } 17 | 18 | document.getElementById("chat_btn").addEventListener("click", function(){ 19 | window.tidioChatApi.show(); 20 | window.tidioChatApi.open(); 21 | }); 22 | })(); 23 | else if theme.chat_hide_show 24 | script. 25 | function chatBtnHide () { 26 | if (window.tidioChatApi) { 27 | window.tidioChatApi.hide(); 28 | //- document.getElementById('tidio-chat').style.display= 'none' 29 | } 30 | } 31 | 32 | function chatBtnShow () { 33 | if (window.tidioChatApi) { 34 | window.tidioChatApi.show(); 35 | //- document.getElementById('tidio-chat').style.display= 'block' 36 | } 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/disqus.pug: -------------------------------------------------------------------------------- 1 | #disqus_thread 2 | script. 3 | function loadDisqus () { 4 | var disqus_config = function () { 5 | this.page.url = '!{ page.permalink }'; 6 | this.page.identifier = '!{ page.path }'; 7 | this.page.title = '!{ page.title }'; 8 | }; 9 | 10 | var d = document, s = d.createElement('script'); 11 | s.src = 'https://!{theme.disqus.shortname}.disqus.com/embed.js'; 12 | s.setAttribute('data-timestamp', +new Date()); 13 | (d.head || d.body).appendChild(s); 14 | } 15 | 16 | if ('!{defaultComment}' === 'Disqus' || !{theme.comments.load_begin}) { 17 | window.addEventListener('load', loadDisqus) 18 | } 19 | else { 20 | function loadOtherComment () { 21 | loadDisqus() 22 | } 23 | } 24 | 25 | if is_post() && theme.comments.count && defaultComment === 'Disqus' 26 | script. 27 | function getDisqusCount() { 28 | var d = document, s = d.createElement('script'); 29 | s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js'; 30 | s.id = 'dsq-count-scr'; 31 | (d.head || d.body).appendChild(s); 32 | } 33 | 34 | window.addEventListener('load', getDisqusCount, false); -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/disqusjs.pug: -------------------------------------------------------------------------------- 1 | #disqus_thread 2 | script. 3 | function loadDisqusjs () { 4 | const ele = document.createElement('link') 5 | ele.rel = 'stylesheet' 6 | ele.href= '!{url_for(theme.CDN.disqusjs_css)}' 7 | document.getElementsByTagName('head')[0].appendChild(ele) 8 | 9 | loadScript('!{url_for(theme.CDN.disqusjs)}', function() { 10 | var dsqjs = new DisqusJS({ 11 | shortname: '!{theme.disqusjs.shortname}', 12 | siteName: '!{theme.disqusjs.siteName}', 13 | identifier: '!{ page.path }', 14 | url: '!{ page.permalink }', 15 | title: '!{ page.title }', 16 | api: '!{theme.disqusjs.api}', 17 | apikey: '!{theme.disqusjs.apikey}', 18 | nocomment: '!{theme.disqusjs.nocomment}', 19 | admin: '!{theme.disqusjs.admin}', 20 | adminLabel: '!{theme.disqusjs.adminLabel}' 21 | }); 22 | }) 23 | } 24 | 25 | if ('!{defaultComment}' === 'Disqusjs' || !{theme.comments.load_begin}) { 26 | window.addEventListener('load', loadDisqusjs) 27 | } 28 | else { 29 | function loadOtherComment () { 30 | loadDisqusjs() 31 | } 32 | } 33 | 34 | 35 | if is_post() && theme.comments.count && defaultComment === 'Disqusjs' 36 | script. 37 | function getDisqusCount() { 38 | var d = document, s = d.createElement('script'); 39 | s.src = 'https://!{theme.disqusjs.shortname}.disqus.com/count.js'; 40 | s.id = 'dsq-count-scr'; 41 | (d.head || d.body).appendChild(s); 42 | } 43 | window.addEventListener('load', getDisqusCount, false); 44 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/facebook_comments.pug: -------------------------------------------------------------------------------- 1 | #fb-root 2 | .fb-comments(data-colorscheme = theme.display_mode === 'dark' ? 'dark' : 'light' 3 | data-href=urlNoIndex() 4 | data-numposts= theme.facebook_comments.pageSize || 10 5 | data-order-by= theme.facebook_comments.order_by || 'social' 6 | data-width="100%") 7 | 8 | script. 9 | function loadFBComent () { 10 | let ele = document.createElement('script') 11 | ele.setAttribute('src','https://connect.facebook.net/!{theme.facebook_comments.lang}/sdk.js#xfbml=1&version=v7.0') 12 | ele.setAttribute('async', 'true') 13 | ele.setAttribute('defer', 'true') 14 | ele.setAttribute('crossorigin', 'anonymous') 15 | document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele) 16 | } 17 | 18 | if ('!{defaultComment}' === 'Facebook Comments' || !{theme.comments.load_begin}) { 19 | window.addEventListener('load', loadFBComent) 20 | } 21 | else { 22 | function loadOtherComment () { 23 | loadFBComent() 24 | } 25 | } 26 | 27 | if theme.darkmode.enable 28 | script. 29 | var themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light' 30 | document.getElementsByClassName('fb-comments')[0].setAttribute('data-colorscheme',themeNow) 31 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/gitalk.pug: -------------------------------------------------------------------------------- 1 | #gitalk-container 2 | script(src=url_for(theme.CDN.blueimp_md5)) 3 | 4 | script. 5 | function loadGitalk () { 6 | const ele = document.createElement('link') 7 | ele.rel = 'stylesheet' 8 | ele.href= '!{url_for(theme.CDN.gitalk_css)}' 9 | document.getElementsByTagName('head')[0].appendChild(ele) 10 | 11 | loadScript('!{url_for(theme.CDN.gitalk)}', function () { 12 | var gitalk = new Gitalk({ 13 | clientID: '!{theme.gitalk.client_id}', 14 | clientSecret: '!{theme.gitalk.client_secret}', 15 | repo: '!{theme.gitalk.repo}', 16 | owner: '!{theme.gitalk.owner}', 17 | admin: ['!{theme.gitalk.admin}'], 18 | id: md5(decodeURI(location.pathname)), 19 | language: '!{theme.gitalk.language}', 20 | perPage: !{theme.gitalk.perPage}, 21 | distractionFreeMode: !{theme.gitalk.distractionFreeMode}, 22 | pagerDirection: '!{theme.gitalk.pagerDirection}', 23 | createIssueManually: !{theme.gitalk.createIssueManually}, 24 | updateCountCallback: commentCount 25 | }) 26 | gitalk.render('gitalk-container') 27 | }) 28 | 29 | function commentCount(n){ 30 | try { 31 | document.getElementsByClassName('gitalk-comment-count')[0].innerHTML= n 32 | } catch (e) { 33 | return false 34 | } 35 | } 36 | } 37 | 38 | if ('!{defaultComment}' === 'Gitalk' || !{theme.comments.load_begin}) { 39 | window.addEventListener('load', loadGitalk) 40 | } 41 | else { 42 | function loadOtherComment () { 43 | loadGitalk() 44 | } 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/index.pug: -------------------------------------------------------------------------------- 1 | if theme.comments && theme.comments.use 2 | - const defaultComment = theme.comments.use[0] 3 | hr 4 | #post-comment 5 | .comment-head 6 | .comment-headling 7 | i.fas.fa-comments.fa-fw 8 | span= ' ' + _p('comment') 9 | 10 | if theme.comments.use.length > 1 11 | .comment-switch 12 | span.first-comment=defaultComment 13 | label 14 | input#switch-comments-btn(type="checkbox") 15 | span.slider 16 | span.second-comment=theme.comments.use[1] 17 | 18 | 19 | .comment-wrap 20 | each name, index in theme.comments.use 21 | div(class=`comments-items-${index+1}` data-name=`${name}`) 22 | case name 23 | when 'Disqus' 24 | include ./disqus.pug 25 | when 'Valine' 26 | include ./valine.pug 27 | when 'Disqusjs' 28 | include ./disqusjs.pug 29 | when 'Livere' 30 | include ./livere.pug 31 | when 'Gitalk' 32 | include ./gitalk.pug 33 | when 'Utterances' 34 | include ./utterances.pug 35 | when 'Facebook Comments' 36 | include ./facebook_comments.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/laibili.pug: -------------------------------------------------------------------------------- 1 | #lv-container(data-id="city" data-uid=theme.laibili.uid) 2 | script. 3 | (function(d, s) { 4 | var j, e = d.getElementsByTagName(s)[0]; 5 | if (typeof LivereTower === 'function') { return; } 6 | j = d.createElement(s); 7 | j.src = 'https://cdn-city.livere.com/js/embed.dist.js'; 8 | j.async = true; 9 | e.parentNode.insertBefore(j, e); 10 | })(document, 'script'); 11 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/livere.pug: -------------------------------------------------------------------------------- 1 | #lv-container(data-id="city" data-uid=theme.livere.uid) 2 | script. 3 | function loadlivere () { 4 | (function(d, s) { 5 | var j, e = d.getElementsByTagName(s)[0]; 6 | if (typeof LivereTower === 'function') { return; } 7 | j = d.createElement(s); 8 | j.src = 'https://cdn-city.livere.com/js/embed.dist.js'; 9 | j.async = true; 10 | e.parentNode.insertBefore(j, e); 11 | })(document, 'script'); 12 | } 13 | 14 | if ('!{defaultComment}' === 'Livere' || !{theme.comments.load_begin}) { 15 | window.addEventListener('load', loadlivere) 16 | } 17 | else { 18 | function loadOtherComment () { 19 | loadlivere() 20 | } 21 | } -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/utterances.pug: -------------------------------------------------------------------------------- 1 | #utterances-wrap 2 | 3 | script. 4 | function loadUtterances () { 5 | let ele = document.createElement('script') 6 | ele.setAttribute('id', 'utterances_comment') 7 | ele.setAttribute('src', '!{url_for(theme.CDN.utterances)}') 8 | ele.setAttribute('repo', '!{theme.utterances.repo}') 9 | ele.setAttribute('issue-term', '!{theme.utterances.issue_term}') 10 | let nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}' 11 | ele.setAttribute('theme', nowTheme) 12 | ele.setAttribute('crossorigin', 'anonymous') 13 | ele.setAttribute('async', 'true') 14 | document.getElementById('utterances-wrap').insertAdjacentElement('afterbegin',ele) 15 | } 16 | 17 | if ('!{defaultComment}' === 'Utterances' || !{theme.comments.load_begin}) { 18 | window.addEventListener('load', loadUtterances) 19 | } 20 | else { 21 | function loadOtherComment () { 22 | loadUtterances() 23 | } 24 | } 25 | 26 | if theme.darkmode.enable 27 | script. 28 | function utterancesTheme () { 29 | var theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}' 30 | const message = { 31 | type: 'set-theme', 32 | theme: theme 33 | }; 34 | const iframe = document.querySelector('.utterances-frame'); 35 | iframe.contentWindow.postMessage(message, 'https://utteranc.es'); 36 | } 37 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/comments/valine.pug: -------------------------------------------------------------------------------- 1 | - let emojiMaps = '""' 2 | if site.data.valine 3 | - emojiMaps = JSON.stringify(site.data.valine) 4 | 5 | #vcomment.vcomment 6 | script. 7 | function loadvaline () { 8 | var requestSetting = function (from,set) { 9 | var from = from 10 | var setting = set.split(',').filter(function(item){ 11 | return from.indexOf(item) > -1 12 | }); 13 | setting = setting.length == 0 ? from :setting; 14 | return setting 15 | } 16 | 17 | var guestInfo = requestSetting(['nick','mail','link'],'#{ theme.valine.guest_info }') 18 | var requiredFields = requestSetting(['nick','mail'],'#{ theme.valine.requiredFields }') 19 | 20 | function initValine () { 21 | window.valine = new Valine({ 22 | el:'#vcomment', 23 | appId: '#{theme.valine.appId}', 24 | appKey: '#{theme.valine.appKey}', 25 | placeholder: '#{theme.valine.placeholder}', 26 | avatar: '#{theme.valine.avatar}', 27 | meta: guestInfo, 28 | pageSize: '#{theme.valine.pageSize}', 29 | lang: '#{theme.valine.lang}', 30 | recordIP: #{theme.valine.recordIP}, 31 | serverURLs: '#{theme.valine.serverURLs}', 32 | emojiCDN: '#{theme.valine.emojiCDN}', 33 | emojiMaps: !{emojiMaps}, 34 | enableQQ: #{theme.valine.enableQQ}, 35 | requiredFields: requiredFields 36 | }); 37 | } 38 | loadScript('!{url_for(theme.CDN.valine)}', initValine) 39 | } 40 | 41 | if ('!{defaultComment}' === 'Valine' || !{theme.comments.load_begin}) { 42 | window.addEventListener('load', loadvaline) 43 | } 44 | else { 45 | function loadOtherComment () { 46 | loadvaline() 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/footer.pug: -------------------------------------------------------------------------------- 1 | #footer-wrap 2 | - var now = new Date() 3 | - var nowYear = now.getFullYear() 4 | if theme.since && theme.since != nowYear 5 | .copyright!= `©${theme.since} - ${nowYear + ' '} ${config.author}` 6 | else 7 | .copyright!= `©${nowYear + ' '} ${config.author}` 8 | if theme.footer_copyright 9 | .framework-info 10 | span= _p('footer.driven') + ' ' 11 | a(href='https://hexo.io') 12 | span Hexo 13 | span.footer-separator | 14 | span= _p('footer.theme') + ' ' 15 | a(href='https://github.com/jerryc127/hexo-theme-butterfly') 16 | span Butterfly 17 | if theme.footer_custom_text 18 | .footer_custom_text!=`${theme.footer_custom_text}` 19 | if theme.ICP.enable 20 | .icp 21 | a(href=theme.ICP.url) 22 | if theme.ICP.icon 23 | img.icp-icon(src=url_for(theme.ICP.icon)) 24 | span=theme.ICP.text 25 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head.pug: -------------------------------------------------------------------------------- 1 | - var pageTitle 2 | - if (is_archive()) pageTitle = _p('page.archives') 3 | - else if (is_tag()) pageTitle = _p('page.tag') + ': ' + page.tag 4 | - else if (is_category()) pageTitle = _p('page.category') + ': ' + page.category 5 | - else if (is_month()) pageTitle += ': ' + page.month + '/' + page.year 6 | - else if (is_year()) pageTitle += ': ' + page.year 7 | - else if (is_current('/404.html', [strict])) pageTitle = _p('error404.error_title') 8 | - else pageTitle = page.title || config.title || '' 9 | 10 | - var isSubtitle = config.subtitle ? ' - ' + config.subtitle : '' 11 | - var tabTitle = is_home() || !pageTitle ? config.title + isSubtitle : pageTitle + ' | ' + config.title 12 | 13 | - var pageDescription = page_description() 14 | - var pageKeywords 15 | - if (page.keywords) pageKeywords = Array.isArray(page.keywords) ? (page.keywords).join(',') : ([]).join(',') || page.keywords 16 | - else if (page.tags && page.tags.length) pageKeywords = page.tags.data.map(function(tag) {return tag.name;}).join(',') 17 | - else pageKeywords = Array.isArray(config.keywords) ? (config.keywords).join(','): ([]).join(',') || config.keywords 18 | - var pageAuthor = config.email ? config.author + ',' + config.email : config.author 19 | - var pageCopyright = config.copyright || config.author 20 | 21 | meta(charset='UTF-8') 22 | meta(http-equiv="X-UA-Compatible" content="IE=edge") 23 | meta(name="viewport" content="width=device-width,initial-scale=1") 24 | title= tabTitle 25 | meta(name="description" content!=pageDescription) 26 | if pageKeywords 27 | meta(name="keywords" content=pageKeywords) 28 | meta(name="author" content=pageAuthor) 29 | meta(name="copyright" content=pageCopyright) 30 | meta(name ="format-detection" content="telephone=no") 31 | !=favicon_tag(theme.favicon || config.favicon) 32 | link(rel="canonical" href=urlNoIndex()) 33 | 34 | if theme.disable_baidu_transformation 35 | meta(http-equiv="Cache-Control" content="no-transform") 36 | meta(http-equiv="Cache-Control" content="no-siteapp") 37 | 38 | if theme.douban 39 | if theme.douban.meta && (is_current('/movies/', [strict]) || is_current('/books/', [strict]) || is_current('/games/', [strict])) 40 | meta(name="referrer" content="no-referrer") 41 | 42 | //- 預解析 43 | !=partial('includes/head/preconnect', {}, {cache:theme.fragment_cache}) 44 | 45 | //- 網站驗證 46 | !=partial('includes/head/site_verification', {}, {cache:theme.fragment_cache}) 47 | 48 | //- Open_Graph 49 | include ./head/Open_Graph.pug 50 | 51 | //- PWA 52 | if (theme.pwa && theme.pwa.enable) 53 | !=partial('includes/head/pwa', {}, {cache:theme.fragment_cache}) 54 | 55 | if theme.darkmode.enable 56 | !=partial('includes/head/darkmode', {}, {cache:theme.fragment_cache}) 57 | 58 | //- main css 59 | link(rel='stylesheet', href=url_for(theme.CDN.main_css)) 60 | link(rel='stylesheet', href=url_for(theme.CDN.fontawesome)) 61 | 62 | if theme.fancybox 63 | link(rel='stylesheet', href=url_for(theme.CDN.fancybox_css)) 64 | 65 | if (theme.snackbar && theme.snackbar.enable) 66 | link(rel='stylesheet', href=url_for(theme.CDN.snackbar_css)) 67 | 68 | if is_post() 69 | if(page.prev) 70 | link(rel="prev" title=page.prev.title href=url_for(page.prev.permalink) ) 71 | if(page.next) 72 | link(rel="next" title=page.next.title href=url_for(page.next.permalink) ) 73 | 74 | if theme.algolia_search.enable 75 | link(rel="stylesheet" type="text/css" href=url_for(theme.CDN.algolia_search_css)) 76 | script(src=url_for(theme.CDN.algolia_search) defer) 77 | 78 | //- comment css 79 | include ./head/comment.pug 80 | 81 | //- google_adsense 82 | !=partial('includes/head/google_adsense', {}, {cache:theme.fragment_cache}) 83 | 84 | //- analytics 85 | !=partial('includes/head/analytics', {}, {cache:theme.fragment_cache}) 86 | 87 | //- font 88 | if theme.blog_title_font.font_link 89 | link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link)) 90 | 91 | //- global config 92 | !=partial('includes/head/config', {}, {cache:theme.fragment_cache}) 93 | 94 | include ./head/config_site.pug 95 | include ./head/noscript.pug 96 | 97 | !=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)}) 98 | 99 | if page.aplayer 100 | include ./head/aplayer.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/Open_Graph.pug: -------------------------------------------------------------------------------- 1 | - var contentType = is_post() ? 'article' : 'website' 2 | 3 | if theme.Open_Graph_meta 4 | meta(property="og:type" content=contentType) 5 | meta(property="og:title" content=pageTitle) 6 | meta(property="og:url" content=urlNoIndex()) 7 | meta(property="og:site_name" content=config.title) 8 | meta(property="og:description" content!=pageDescription) 9 | meta(property="og:image" content=full_url_for(page.cover || theme.avatar.img)) 10 | meta(property="article:published_time" content=date_xml(page.date)) 11 | meta(property="article:modified_time" content=date_xml(page.updated)) 12 | meta(name="twitter:card" content="summary") 13 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/analytics.pug: -------------------------------------------------------------------------------- 1 | if theme.baidu_analytics 2 | script. 3 | var _hmt = _hmt || []; 4 | (function() { 5 | var hm = document.createElement("script"); 6 | hm.src = "https://hm.baidu.com/hm.js?!{theme.baidu_analytics}"; 7 | var s = document.getElementsByTagName("script")[0]; 8 | s.parentNode.insertBefore(hm, s); 9 | })(); 10 | 11 | if theme.google_analytics 12 | script. 13 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 14 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 15 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 16 | })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 17 | 18 | ga('create', '!{theme.google_analytics}', 'auto'); 19 | ga('send', 'pageview'); 20 | 21 | if theme.tencent_analytics 22 | script(src=`https://tajs.qq.com/stats?sId=${theme.tencent_analytics}` charset="UTF-8") 23 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/aplayer.pug: -------------------------------------------------------------------------------- 1 | link(rel='stylesheet' href=url_for(theme.CDN.aplayer_css)) 2 | script(src=url_for(theme.CDN.aplayer_js)) 3 | script(src=url_for(theme.CDN.meting_js)) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/comment.pug: -------------------------------------------------------------------------------- 1 | if page.comments !== false && theme.comments.use && theme.comments.use.includes('Facebook Comments') 2 | if theme.facebook_comments.app_id 3 | meta(property="fb:app_id" content=theme.facebook_comments.app_id ) 4 | if theme.facebook_comments.user_id 5 | meta(property="fb:admins" content=theme.facebook_comments.user_id) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/config.pug: -------------------------------------------------------------------------------- 1 | - 2 | var algolia = 'undefined'; 3 | var env = process.env; 4 | if (theme.algolia_search.enable) { 5 | algolia = JSON.stringify({ 6 | appId: env.ALGOLIA_APP_ID || config.algolia.appId || config.algolia.applicationID, 7 | apiKey: env.ALGOLIA_API_KEY || config.algolia.apiKey, 8 | indexName: env.ALGOLIA_INDEX_NAME || config.algolia.indexName, 9 | hits: theme.algolia_search.hits, 10 | // search languages 11 | languages: { 12 | input_placeholder: _p("algolia_search.input_placeholder"), 13 | hits_empty: _p("algolia_search.hits_empty"), 14 | hits_stats: _p("algolia_search.hits_stats") 15 | } 16 | }) 17 | } 18 | 19 | var localSearch = 'undefined'; 20 | if (theme.local_search && theme.local_search.enable) { 21 | localSearch = JSON.stringify({ 22 | path: config.search.path, 23 | languages: { 24 | // search languages 25 | hits_empty: _p("local_search.hits_empty") 26 | } 27 | }) 28 | } 29 | var translate = 'undefined'; 30 | if (theme.translate && theme.translate.enable){ 31 | translate = JSON.stringify({ 32 | defaultEncoding: theme.translate.defaultEncoding, 33 | translateDelay: theme.translate.translateDelay, 34 | msgToTraditionalChinese: theme.translate.msgToTraditionalChinese, 35 | msgToSimplifiedChinese: theme.translate.msgToSimplifiedChinese 36 | }) 37 | } 38 | 39 | var copyright = 'undefined' ; 40 | if (theme.copy.enable && theme.copy.copyright){ 41 | copyright = JSON.stringify({ 42 | languages: { 43 | author: _p("copy_copyright.author") + ': ' + config.author, 44 | link: _p("copy_copyright.link") + ': ', 45 | source: _p("copy_copyright.source") + ': ' + config.title, 46 | info: _p("copy_copyright.info") 47 | } 48 | }) 49 | } 50 | 51 | var ClickShowText = 'undefined'; 52 | if (theme.ClickShowText && theme.ClickShowText.enable) { 53 | ClickShowText = JSON.stringify({ 54 | text: theme.ClickShowText.text.join(","), 55 | fontSize: theme.ClickShowText.fontSize 56 | }) 57 | } 58 | 59 | 60 | var Snackbar = 'undefined'; 61 | if (theme.snackbar && theme.snackbar.enable) { 62 | Snackbar = JSON.stringify({ 63 | bookmark: { 64 | message_prev: _p("Snackbar.bookmark.message_prev"), 65 | message_next: _p("Snackbar.bookmark.message_next") 66 | }, 67 | chs_to_cht: _p("Snackbar.chs_to_cht"), 68 | cht_to_chs: _p("Snackbar.cht_to_chs"), 69 | day_to_night: _p("Snackbar.day_to_night"), 70 | night_to_day: _p("Snackbar.night_to_day"), 71 | bgLight: theme.snackbar.bg_light, 72 | bgDark: theme.snackbar.bg_dark, 73 | position: theme.snackbar.position, 74 | }) 75 | } 76 | 77 | var noticeOutdate = 'undefined'; 78 | if (theme.noticeOutdate && theme.noticeOutdate.enable) { 79 | noticeOutdate = JSON.stringify({ 80 | limitDay: theme.noticeOutdate.limit_day, 81 | position: theme.noticeOutdate.position, 82 | messagePrev: theme.noticeOutdate.message_prev, 83 | messageNext: theme.noticeOutdate.message_next, 84 | }) 85 | } 86 | 87 | script. 88 | var GLOBAL_CONFIG = { 89 | root: '!{config.root}', 90 | algolia: !{algolia}, 91 | localSearch: !{localSearch}, 92 | translate: !{translate}, 93 | noticeOutdate: !{noticeOutdate}, 94 | copy: { 95 | success: '!{_p("copy.success")}', 96 | error: '!{_p("copy.error")}', 97 | noSupport: '!{_p("copy.noSupport")}' 98 | }, 99 | bookmark: { 100 | message_prev: '!{_p("Snackbar.bookmark.message_prev")}', 101 | message_next: '!{_p("Snackbar.bookmark.message_next")}' 102 | }, 103 | runtime_unit: '!{_p("runtime_unit")}', 104 | runtime: !{theme.runtimeshow.enable}, 105 | copyright: !{copyright}, 106 | ClickShowText: !{ClickShowText}, 107 | medium_zoom: !{theme.medium_zoom}, 108 | fancybox: !{theme.fancybox}, 109 | Snackbar: !{Snackbar}, 110 | justifiedGallery: { 111 | js: '!{theme.CDN.justifiedGallery_js}', 112 | css: '!{theme.CDN.justifiedGallery_css}' 113 | }, 114 | baiduPush: !{theme.baidu_push}, 115 | highlightCopy: !{theme.highlight_copy}, 116 | highlightLang: !{theme.highlight_lang}, 117 | isPhotoFigcaption: !{theme.photofigcaption}, 118 | islazyload: !{theme.lazyload.enable}, 119 | isanchor: !{theme.anchor} 120 | } 121 | 122 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/config_site.pug: -------------------------------------------------------------------------------- 1 | - 2 | let isHighlightShrink 3 | if (theme.highlight_shrink == 'none') isHighlightShrink = 'undefined' 4 | else if (page.highlight_shrink === true || page.highlight_shrink === false) isHighlightShrink = page.highlight_shrink 5 | else isHighlightShrink = theme.highlight_shrink 6 | 7 | const pageToc = page.toc === true || page.toc === false ? page.toc : theme.toc.enable 8 | const showToc = is_post() && pageToc && (toc(page.content) !== '' || page.encrypt == true ) 9 | - 10 | 11 | script. 12 | var GLOBAL_CONFIG_SITE = { 13 | isPost: !{is_post()}, 14 | isHome: !{is_home()}, 15 | isHighlightShrink: !{isHighlightShrink}, 16 | isSidebar: !{showToc}, 17 | postUpdate: '!{full_date(page.updated)}' 18 | } 19 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/darkmode.pug: -------------------------------------------------------------------------------- 1 | script. 2 | var activateDarkMode = function () { 3 | document.documentElement.setAttribute('data-theme', 'dark') 4 | if (document.querySelector('meta[name="theme-color"]') !== null) { 5 | document.querySelector('meta[name="theme-color"]').setAttribute('content', '#000') 6 | } 7 | } 8 | var activateLightMode = function () { 9 | document.documentElement.setAttribute('data-theme', 'light') 10 | if (document.querySelector('meta[name="theme-color"]') !== null) { 11 | document.querySelector('meta[name="theme-color"]').setAttribute('content', '#fff') 12 | } 13 | } 14 | 15 | var getCookies = function (name) { 16 | const value = `; ${document.cookie}` 17 | const parts = value.split(`; ${name}=`) 18 | if (parts.length === 2) return parts.pop().split(';').shift() 19 | } 20 | 21 | var autoChangeMode = '#{theme.darkmode.autoChangeMode}' 22 | var t = getCookies('theme') 23 | if (autoChangeMode === '1') { 24 | var isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches 25 | var isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches 26 | var isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches 27 | var hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified 28 | 29 | if (t === undefined) { 30 | if (isLightMode) activateLightMode() 31 | else if (isDarkMode) activateDarkMode() 32 | else if (isNotSpecified || hasNoSupport) { 33 | console.log('You specified no preference for a color scheme or your browser does not support it. I Schedule dark mode during night time.') 34 | var now = new Date() 35 | var hour = now.getHours() 36 | var isNight = hour <= 6 || hour >= 18 37 | isNight ? activateDarkMode() : activateLightMode() 38 | } 39 | window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) { 40 | if (Cookies.get('theme') === undefined) { 41 | e.matches ? activateDarkMode() : activateLightMode() 42 | } 43 | }) 44 | } else if (t === 'light') activateLightMode() 45 | else activateDarkMode() 46 | } else if (autoChangeMode === '2') { 47 | now = new Date() 48 | hour = now.getHours() 49 | isNight = hour <= 6 || hour >= 18 50 | if (t === undefined) isNight ? activateDarkMode() : activateLightMode() 51 | else if (t === 'light') activateLightMode() 52 | else activateDarkMode() 53 | } else { 54 | if (t === 'dark') activateDarkMode() 55 | else if (t === 'light') activateLightMode() 56 | } 57 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/dns_prefetch.pug: -------------------------------------------------------------------------------- 1 | link(rel="preconnect" href="//cdn.jsdelivr.net") 2 | 3 | if theme.google_analytics 4 | link(rel="preconnect" href="https://www.google-analytics.com" crossorigin) 5 | 6 | if theme.baidu_analytics 7 | link(rel="preconnect" href="https://hm.baidu.com") 8 | 9 | if theme.tencent_analytics 10 | link(rel="preconnect" href="http://ta.qq.com") 11 | 12 | if theme.blog_title_font.font_link 13 | link(rel="preconnect" href="https://fonts.googleapis.com" crossorigin) 14 | 15 | if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv 16 | link(rel="preconnect" href="//busuanzi.ibruce.info") 17 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/google_adsense.pug: -------------------------------------------------------------------------------- 1 | if (theme.google_adsense && theme.google_adsense.enable) 2 | script(async src=theme.google_adsense.js) 3 | script. 4 | (adsbygoogle = window.adsbygoogle || []).push({ 5 | google_ad_client: '!{theme.google_adsense.client}', 6 | enable_page_level_ads: '!{theme.google_adsense.enable_page_level_ads}' 7 | }); -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/noscript.pug: -------------------------------------------------------------------------------- 1 | noscript. 2 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/preconnect.pug: -------------------------------------------------------------------------------- 1 | link(rel="preconnect" href="//cdn.jsdelivr.net") 2 | 3 | if theme.google_analytics 4 | link(rel="preconnect" href="//www.google-analytics.com" crossorigin) 5 | 6 | if theme.baidu_analytics 7 | link(rel="preconnect" href="//hm.baidu.com") 8 | 9 | if theme.tencent_analytics 10 | link(rel="preconnect" href="//ta.qq.com") 11 | 12 | if theme.blog_title_font.font_link && theme.blog_title_font.font_link.indexOf('//fonts.googleapis.com') != -1 13 | link(rel="preconnect" href="//fonts.googleapis.com" crossorigin) 14 | 15 | if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv 16 | link(rel="preconnect" href="//busuanzi.ibruce.info") 17 | 18 | if theme.baidu_push 19 | link(rel="preconnect" href="//zz.bdstatic.com") 20 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/pwa.pug: -------------------------------------------------------------------------------- 1 | link(rel="manifest" href=url_for(theme.pwa.manifest)) 2 | if(theme.pwa.theme_color) 3 | meta(name="theme-color" content=theme.pwa.theme_color) 4 | if(theme.pwa.theme_color) 5 | meta(name="msapplication-TileColor" content=theme.pwa.theme_color) 6 | if(theme.pwa.apple_touch_icon) 7 | link(rel="apple-touch-icon" sizes="180x180" href=url_for(theme.pwa.apple_touch_icon)) 8 | if(theme.pwa.favicon_32_32) 9 | link(rel="icon" type="image/png" sizes="32x32" href=url_for(theme.pwa.favicon_32_32)) 10 | if(theme.pwa.favicon_16_16) 11 | link(rel="icon" type="image/png" sizes="16x16" href=url_for(theme.pwa.favicon_16_16)) 12 | if(theme.pwa.mask_icon) 13 | link(rel="mask-icon" href=url_for(theme.pwa.mask_icon) color="#5bbad5") 14 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/head/site_verification.pug: -------------------------------------------------------------------------------- 1 | if theme.google_site_verification 2 | meta(name="google-site-verification" content=theme.google_site_verification) 3 | 4 | if theme.bing_site_verification 5 | meta(name="msvalidate.01" content=theme.bing_site_verification) 6 | 7 | if theme.baidu_site_verification 8 | meta(name="baidu-site-verification" content=theme.baidu_site_verification) 9 | 10 | if theme.qihu_site_verification 11 | meta(name="360-site-verification" content=theme.qihu_site_verification) 12 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/header/header.pug: -------------------------------------------------------------------------------- 1 | #page-header 2 | span#blog_name.pull_left 3 | a#site-name.blog_title(href=url_for('/')) #[=config.title] 4 | 5 | span.pull_right.menus 6 | if (theme.algolia_search.enable || theme.local_search && theme.local_search.enable) 7 | #search_button 8 | a.site-page.social-icon.search 9 | i.fa.fa-search.fa-fw 10 | span=' '+_p('search') 11 | !=fragment_cache('menus', function(){return partial('includes/header/menu_item')}) 12 | 13 | span.toggle-menu.close 14 | a.site-page 15 | i.fa.fa-bars.fa-fw(aria-hidden="true") 16 | 17 | 18 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/header/index.pug: -------------------------------------------------------------------------------- 1 | if is_home() 2 | - var top_img = theme.index_img || theme.default_top_img 3 | else if is_post() 4 | - var top_img = page.top_img || page.cover || page.randomcover || theme.default_top_img 5 | else if is_archive() 6 | - var top_img = theme.archive_img || theme.default_top_img 7 | else if is_tag() 8 | - var top_img = theme.tag_img || theme.default_top_img 9 | else if is_category() 10 | - var top_img = theme.category_img || theme.default_top_img 11 | else 12 | - var top_img = page.top_img || theme.default_top_img 13 | 14 | if theme.douban 15 | if is_current('/movies/', [strict]) 16 | - var top_img = theme.douban.movies_img || theme.default_top_img 17 | else if is_current('/books/', [strict]) 18 | - var top_img = theme.douban.books_img || theme.default_top_img 19 | else if is_current('/games/', [strict]) 20 | - var top_img = theme.douban.games_img || theme.default_top_img 21 | 22 | - var bg_img = top_img && top_img !== true ? `background-image: url(${url_for(top_img)})` : '' 23 | - var site_title = is_archive() ? _p('page.archives') : page.title || page.tag || page.category || config.title 24 | - var isHomeClass = is_home() ? 'full_page' : 'not-index-bg' 25 | - is_post() ? isHomeClass = 'post-bg' : isHomeClass 26 | 27 | header#page-header(class=isHomeClass style=bg_img) 28 | !=partial('includes/header/nav', {}, {cache:theme.fragment_cache}) 29 | if is_home() 30 | #site-info 31 | h1#site_title=site_title 32 | #site_subtitle 33 | span#subtitle 34 | if(theme.social) 35 | #site_social_icons 36 | !=fragment_cache('social', function(){return partial('includes/header/social')}) 37 | #scroll_down 38 | i.fas.fa-angle-down.scroll-down-effects 39 | else if is_post() 40 | include ./post-info.pug 41 | else 42 | #page_site-info 43 | h1#site_title=site_title 44 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/header/menu_item.pug: -------------------------------------------------------------------------------- 1 | .menus_items 2 | each value, label in theme.menu 3 | if !Array.isArray(value) 4 | .menus_item 5 | a.site-page(href=url_for(trim(value.split('||')[0]))) 6 | if value.split('||')[1] 7 | i.fa-fw(class=trim(value.split('||')[1])) 8 | span=' '+label 9 | else 10 | .menus_item 11 | a.site-page 12 | if label.split('||')[1] 13 | i.fa-fw(class=trim(label.split('||')[1]) ) 14 | span=' '+ trim(label.split('||')[0]) 15 | i.fas.fa-chevron-down.menus-expand 16 | ul.menus_item_child 17 | each i in value 18 | li 19 | a.site-page(href=url_for(trim(i.split('||')[1]))) 20 | if i.split('||')[2] 21 | i.fa-fw(class=trim(i.split('||')[2])) 22 | span=' '+trim(i.split('||')[0]) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/header/nav.pug: -------------------------------------------------------------------------------- 1 | nav#nav 2 | span#blog_name.pull-left 3 | a#site-name.blog_title(href=url_for('/')) #[=config.title] 4 | 5 | span.pull-right.menus 6 | if (theme.algolia_search.enable || theme.local_search && theme.local_search.enable) 7 | #search_button 8 | a.site-page.social-icon.search 9 | i.fas.fa-search.fa-fw 10 | span=' '+_p('search') 11 | !=fragment_cache('menus', function(){return partial('includes/header/menu_item')}) 12 | 13 | span.toggle-menu.close 14 | a.site-page 15 | i.fas.fa-bars.fa-fw 16 | 17 | 18 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/header/post-info.pug: -------------------------------------------------------------------------------- 1 | #post-info 2 | #post-title 3 | .posttitle= page.title || _p('no_title') 4 | 5 | #post-meta 6 | .meta-firstline 7 | if (theme.post_meta.post.date_type) 8 | if (theme.post_meta.post.date_type === 'both') 9 | time.post-meta__date 10 | span.post-meta__date-created(title= _p('post.created')+' '+full_date(page.date)) 11 | i.far.fa-calendar-alt.fa-fw 12 | =' '+_p('post.created')+' '+date(page.date, config.date_format) 13 | span.post-meta__separator | 14 | span.post-meta__date-updated(title= _p('post.updated')+' '+full_date(page.updated)) 15 | i.fas.fa-history.fa-fw 16 | =' '+_p('post.updated')+' '+date(page.updated, config.date_format) 17 | else 18 | - var data_type_update = theme.post_meta.post.date_type === 'updated' 19 | - var date_type = data_type_update ? 'updated' : 'date' 20 | - var date_icon = data_type_update ? 'fas fa-history' :'far fa-calendar-alt' 21 | - var data_info = data_type_update ? _p('post.updated') : _p('post.created') 22 | time.post-meta__date(title=data_info + ' ' + full_date(page[date_type])) 23 | i.fa-fw(class=date_icon) 24 | =' ' + data_info + ' ' + date(page[date_type], config.date_format) 25 | 26 | if (theme.post_meta.post.categories && page.categories.data.length > 0) 27 | span.post-meta__categories 28 | if (theme.post_meta.post.date_type) 29 | span.post-meta__separator | 30 | 31 | each item, index in page.categories.data 32 | i.fas.fa-inbox.fa-fw.post-meta__icon 33 | a(href=url_for(item.path)).post-meta__categories #[=item.name] 34 | if (index < page.categories.data.length - 1) 35 | i.fas.fa-angle-right.post-meta__separator 36 | 37 | .meta-secondline 38 | - let postWordcount = theme.wordcount.enable && (theme.wordcount.post_wordcount || theme.wordcount.min2read) 39 | if (postWordcount) 40 | span.post-meta-wordcount 41 | if theme.wordcount.post_wordcount 42 | i.far.fa-file-word.fa-fw.post-meta__icon 43 | span= _p('post.wordcount') + ':' 44 | span.word-count= wordcount(page.content) 45 | if theme.wordcount.min2read 46 | span.post-meta__separator | 47 | if theme.wordcount.min2read 48 | i.far.fa-clock.fa-fw.post-meta__icon 49 | span= _p('post.min2read', min2read(page.content, {cn: 350, en: 160})) 50 | 51 | .meta-thirdline 52 | span.post-meta-pv-cv 53 | if (postWordcount && theme.busuanzi.page_pv) 54 | span.post-meta__separator | 55 | if theme.busuanzi.page_pv 56 | i.far.fa-eye.fa-fw.post-meta__icon 57 | span=_p('post.page_pv') + ':' 58 | span#busuanzi_value_page_pv 59 | 60 | if page.comments !== false && theme.comments.use && theme.comments.count 61 | span.post-meta-commentcount 62 | 63 | - let whichCount = theme.comments.use[0] 64 | if whichCount === 'Disqus' || whichCount === 'Disqusjs' 65 | if (postWordcount || theme.busuanzi.page_pv) 66 | span.post-meta__separator | 67 | i.far.fa-comments.fa-fw.post-meta__icon 68 | span= _p('post.comments') + ':' 69 | span.disqus-comment-count.comment-count 70 | a(href=full_url_for(page.path) + '#disqus_thread') 71 | else if whichCount === 'Valine' 72 | if (postWordcount || theme.busuanzi.page_pv) 73 | span.post-meta__separator | 74 | i.far.fa-comments.fa-fw.post-meta__icon 75 | span= _p('post.comments') + ':' 76 | a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl") 77 | span.valine-comment-count.comment-count(data-xid=url_for(page.path) itemprop="commentCount") 78 | else if whichCount === 'Gitalk' 79 | if (postWordcount || theme.busuanzi.page_pv) 80 | span.post-meta__separator | 81 | i.far.fa-comments.fa-fw.post-meta__icon 82 | span= _p('post.comments') + ':' 83 | a(href=url_for(page.path) + '#post-comment') 84 | span.gitalk-comment-count.comment-count 85 | else if whichCount === 'Facebook Comments' 86 | if (postWordcount || theme.busuanzi.page_pv) 87 | span.post-meta__separator | 88 | i.far.fa-comments.fa-fw.post-meta__icon 89 | span= _p('post.comments') + ':' 90 | a.comment-count(href=url_for(page.path) + '#post-comment') 91 | span.fb-comments-count(data-href=urlNoIndex()) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/header/social.pug: -------------------------------------------------------------------------------- 1 | each url, icon in theme.social 2 | a.social-icon(href=url_for(trim(url.split('||')[0])) target="_blank" 3 | title=url.split('||')[1] === undefined ? '' : trim(url.split('||')[1])) 4 | i(class=icon) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/layout.pug: -------------------------------------------------------------------------------- 1 | - var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : '' 2 | - var pageHighlightShrinkSet = page.highlight_shrink === true || page.highlight_shrink === false ? page.highlight_shrink : theme.highlight_shrink 3 | - var pageHighlightShrink = theme.highlight_shrink !== 'none' && pageHighlightShrinkSet ? 'code-close' : '' 4 | 5 | doctype html 6 | html(lang=config.language data-theme=theme.display_mode) 7 | head 8 | include ./head.pug 9 | body 10 | if theme.preloader 11 | !=partial('includes/loading/loading', {}, {cache:theme.fragment_cache}) 12 | 13 | if theme.fireworks && theme.fireworks.enable 14 | canvas.fireworks 15 | 16 | !=partial('includes/mobile-sidebar/index', {}, {cache:theme.fragment_cache}) 17 | 18 | include ./sidebar.pug 19 | 20 | #body-wrap(class=pageHighlightShrink) 21 | if theme.background 22 | - var is_photo = theme.background.startsWith('url') ? 'photo':'color' 23 | #web_bg(data-type=is_photo) 24 | 25 | include ./header/index.pug 26 | 27 | if (!is_post()) 28 | main#content-inner.layout_page(class=hideAside) 29 | if body 30 | div!= body 31 | else 32 | block content 33 | include widget/index.pug 34 | else 35 | main#content-inner.layout_post 36 | if body 37 | div!= body 38 | else 39 | block content 40 | 41 | - var footer_bg = theme.footer_bg == false ? '' : bg_img 42 | - var is_bg = theme.footer_bg == false ? 'color' : 'photo' 43 | footer#footer(style=footer_bg data-type=is_bg) 44 | !=partial('includes/footer', {}, {cache:theme.fragment_cache}) 45 | 46 | include ./rightside.pug 47 | !=partial('includes/search/index', {}, {cache:theme.fragment_cache}) 48 | include ./additional-js.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/loading/loading-js.pug: -------------------------------------------------------------------------------- 1 | script. 2 | var endLoading = function () { 3 | document.body.style.overflow = 'auto'; 4 | document.getElementById('loading-box').classList.add("loaded") 5 | } 6 | window.addEventListener('load',endLoading) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/loading/loading.pug: -------------------------------------------------------------------------------- 1 | #loading-box 2 | .loading-left-bg 3 | .loading-right-bg 4 | .spinner-box 5 | .configure-border-1 6 | .configure-core 7 | .configure-border-2 8 | .configure-core 9 | .loading-word= _p('loading') 10 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/math/index.pug: -------------------------------------------------------------------------------- 1 | if theme.mathjax && theme.mathjax.enable 2 | if theme.mathjax.per_page 3 | if(!is_tag() && !is_category() && !is_archive() && !is_home()) 4 | include ./mathjax.pug 5 | else 6 | if page.mathjax 7 | include ./mathjax.pug 8 | 9 | if theme.katex && theme.katex.enable 10 | if theme.katex.per_page 11 | if(!is_tag() && !is_category() && !is_archive() && !is_home()) 12 | include ./katex.pug 13 | else 14 | if page.katex 15 | include ./katex.pug 16 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/math/katex.pug: -------------------------------------------------------------------------------- 1 | link(rel="stylesheet" type="text/css" href=theme.CDN.katex) 2 | script(src=url_for(theme.CDN.katex_copytex)) 3 | link(rel="stylesheet" type="text/css" href=theme.CDN.katex_copytex_css) 4 | script. 5 | $(function () { 6 | $('span.katex-display').wrap('
') 7 | }) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/math/mathjax.pug: -------------------------------------------------------------------------------- 1 | script(type="text/x-mathjax-config"). 2 | MathJax.Hub.Config({ 3 | tex2jax: { 4 | inlineMath: [ ['$','$'], ["\\(","\\)"] ], 5 | processEscapes: true, 6 | skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'] 7 | }, 8 | CommonHTML: { 9 | linebreaks: { automatic: true, width: "90% container" } 10 | }, 11 | "HTML-CSS": { 12 | linebreaks: { automatic: true, width: "90% container" } 13 | }, 14 | "SVG": { 15 | linebreaks: { automatic: true, width: "90% container" } 16 | } 17 | }); 18 | 19 | script(type="text/x-mathjax-config"). 20 | MathJax.Hub.Queue(function() { 21 | var all = MathJax.Hub.getAllJax(), i; 22 | for (i=0; i < all.length; i += 1) { 23 | all[i].SourceElement().parentNode.className += ' has-jax'; 24 | } 25 | }); 26 | 27 | script(src=theme.CDN.mathjax) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/math/mermaid.pug: -------------------------------------------------------------------------------- 1 | script. 2 | if (document.getElementsByClassName('mermaid').length) { 3 | loadScript('!{theme.CDN.mermaid}',function () { 4 | mermaid.initialize({ 5 | theme: '!{theme.mermaid.theme}', 6 | }) 7 | }) 8 | } -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/mixins/article-sort.pug: -------------------------------------------------------------------------------- 1 | mixin articleSort(posts) 2 | .article-sort 3 | - var year 4 | - posts.each(function (article) { 5 | - var tempYear = date(article.date, 'YYYY') 6 | - var no_cover = article.cover === false || !theme.cover.archives_enable ? 'no-article-cover' : '' 7 | if tempYear !== year 8 | - year = tempYear 9 | .article-sort-item.year= year 10 | .article-sort-item(class=no_cover) 11 | if article.cover && theme.cover.archives_enable 12 | .article-sort-img 13 | a.article-sort-item__img(href=url_for(article.path)) 14 | img(src=url_for(article.cover) alt=article.title || 'No Title' onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'`) 15 | .article-sort-post 16 | a.article-sort-item__post(href=url_for(article.path)) 17 | i.far.fa-calendar-alt 18 | time.article-sort-item__time(title=_p('post.created') + ' ' + full_date(article.date))= date(article.date, config.date_format) 19 | .article-sort-item__title= article.title || 'No Title' 20 | - }) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/mixins/post-ui.pug: -------------------------------------------------------------------------------- 1 | mixin postUI(posts) 2 | each article , index in page.posts.data 3 | .recent-post-item 4 | - var link = article.link || article.path 5 | - var title = article.title || _p('no_title') 6 | - var leftOrRight = index%2 == 0 ? 'left_radius' : 'right_radius' 7 | - var post_cover = article.cover 8 | - var no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : '' 9 | if post_cover && theme.cover.index_enable 10 | .post_cover(class=leftOrRight) 11 | a(href=url_for(link) title=title) 12 | if theme.lazyload.enable 13 | img.post_bg(data-src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=title) 14 | else 15 | img.post_bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=title) 16 | .recent-post-info(class=no_cover) 17 | a.article-title(href=url_for(link) title=title)= title 18 | .article-meta-wrap 19 | if (is_home() && (article.top || article.sticky > 0)) 20 | span.article-meta 21 | i.fas.fa-thumbtack.article-meta__icon.sticky 22 | span.sticky= _p('sticky') 23 | span.article-meta__separator | 24 | if (theme.post_meta.page.date_type) 25 | if (theme.post_meta.page.date_type === 'both') 26 | time.post-meta__date 27 | span.post-meta__date-created(title=_p('post.created') + ' ' + full_date(article.date)) 28 | i.far.fa-calendar-alt 29 | =date(article.date, config.date_format) 30 | span.article-meta__separator | 31 | span.post-meta__date-updated(title=_p('post.updated') + ' ' + full_date(article.updated)) 32 | i.fas.fa-history 33 | =date(article.updated, config.date_format) 34 | else 35 | - var data_type_updated = theme.post_meta.page.date_type === 'updated' 36 | - var date_type = data_type_updated ? 'updated' : 'date' 37 | - var date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt' 38 | - var date_title = data_type_updated ? _p('post.updated') : _p('post.created') 39 | time.post-meta__date(title=date_title + ' ' + full_date(article[date_type])) 40 | i(class=date_icon) 41 | =date(article[date_type], config.date_format) 42 | if (theme.post_meta.page.categories && article.categories.data.length > 0) 43 | span.article-meta 44 | span.article-meta__separator | 45 | i.fas.fa-inbox.article-meta__icon 46 | each item, index in article.categories.data 47 | a(href=url_for(item.path)).article-meta__categories #[=item.name] 48 | if (index < article.categories.data.length - 1) 49 | i.fas.fa-angle-right 50 | if (theme.post_meta.page.tags && article.tags.data.length > 0) 51 | span.article-meta.tags 52 | span.article-meta__separator | 53 | i.fas.fa-tag.article-meta__icon 54 | each item, index in article.tags.data 55 | a(href=url_for(item.path)).article-meta__tags #[=item.name] 56 | if (index < article.tags.data.length - 1) 57 | span.article-meta__link #[='•'] 58 | 59 | //- Display the article introduction on homepage 60 | if theme.index_post_content.method == 1 61 | .content!= article.description 62 | else if theme.index_post_content.method == 2 63 | if article.description 64 | .content!= article.description 65 | else 66 | - const content = strip_html(article.content) 67 | - let expert = content.substring(0, theme.index_post_content.length) 68 | - content.length > theme.index_post_content.length ? expert += ' ...' : '' 69 | .content!= expert 70 | else 71 | - const content = strip_html(article.content) 72 | - let expert = content.substring(0, theme.index_post_content.length) 73 | - content.length > theme.index_post_content.length ? expert += ' ...' : '' 74 | .content!= expert 75 | 76 | if theme.ad && theme.ad.index 77 | if (index + 1) % 3 == 0 78 | .recent-post-item.ad_height!=theme.ad.index 79 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/mobile-sidebar/index.pug: -------------------------------------------------------------------------------- 1 | #mobile-sidebar 2 | #menu_mask 3 | include ../mobile-sidebar/mobile-menus.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/mobile-sidebar/mobile-menus.pug: -------------------------------------------------------------------------------- 1 | #mobile-sidebar-menus 2 | .mobile_author_icon 3 | img.avatar-img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar") 4 | .mobile_post_data 5 | if site.posts.length 6 | .mobile_data_item.is-center 7 | .mobile_data_link 8 | a(href=url_for(config.archive_dir) + '/') 9 | .headline= _p('aside.articles') 10 | .length_num= site.posts.length 11 | 12 | if site.tags.length 13 | .mobile_data_item.is-center 14 | .mobile_data_link 15 | a(href=url_for(config.tag_dir) + '/' ) 16 | .headline= _p('aside.tags') 17 | .length_num= site.tags.length 18 | 19 | if site.categories.length 20 | .mobile_data_item.is-center 21 | .mobile_data_link 22 | a(href=url_for(config.category_dir) + '/') 23 | .headline= _p('aside.categories') 24 | .length_num= site.categories.length 25 | hr 26 | !=fragment_cache('menus', function(){return partial('includes/header/menu_item')}) 27 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/pagination.pug: -------------------------------------------------------------------------------- 1 | - 2 | var options = { 3 | prev_text: '', 4 | next_text: '', 5 | mid_size: 1, 6 | escape: false 7 | } 8 | 9 | if(!is_post()) 10 | nav#pagination 11 | div.pagination 12 | !=paginator(options) 13 | else 14 | nav#pagination.pagination-post 15 | if(page.prev) 16 | - var hasPageNext = page.next ? 'pull-left' : 'pull-full' 17 | .prev-post(class=hasPageNext) 18 | - var pagination_cover = page.prev.cover === false ? page.prev.randomcover : page.prev.cover 19 | a(href=url_for(page.prev.path)) 20 | if theme.lazyload.enable 21 | img.prev-cover(data-src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` ) 22 | else 23 | img.prev-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` ) 24 | .pagination-info 25 | .label=_p('pagination.prev') 26 | .prev_info=page.prev.title 27 | 28 | if(page.next) 29 | - var hasPagePrev = page.prev ? 'pull-right' : 'pull-full' 30 | - var pagination_cover = page.next.cover == false ? page.next.randomcover : page.next.cover 31 | .next-post(class=hasPagePrev) 32 | a(href=url_for(page.next.path)) 33 | if theme.lazyload.enable 34 | img.next-cover(data-src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'`) 35 | else 36 | img.next-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'`) 37 | .pagination-info 38 | .label=_p('pagination.next') 39 | .next_info=page.next.title -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/post/post-copyright.pug: -------------------------------------------------------------------------------- 1 | if theme.post_copyright.enable && page.copyright !== false 2 | - let author = page.copyright_author ? page.copyright_author : config.author 3 | - let authorHref = page.copyright_author_href ? page.copyright_author_href : `mailto:${config.email}` 4 | - let url = page.copyright_url ? page.copyright_url : page.permalink 5 | - let info = page.copyright_info ? page.copyright_info : _p('post.copyright.copyright_content', theme.post_copyright.license_url, theme.post_copyright.license, config.url, config.title) 6 | .post-copyright 7 | .post-copyright__author 8 | span.post-copyright-meta= _p('post.copyright.author') + ": " 9 | span.post-copyright-info 10 | a(href=authorHref)=author 11 | .post-copyright__type 12 | span.post-copyright-meta= _p('post.copyright.link') + ": " 13 | span.post-copyright-info 14 | a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url 15 | .post-copyright__notice 16 | span.post-copyright-meta= _p('post.copyright.copyright_notice') + ": " 17 | span.post-copyright-info!= info 18 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/post/reward.pug: -------------------------------------------------------------------------------- 1 | .post-reward 2 | button.reward-button(type="button") 3 | i.fas.fa-qrcode 4 | = ' ' + _p('donate') 5 | .reward-main 6 | ul.reward-all 7 | each item in theme.reward.QR_code 8 | - var clickTo = (item.itemlist||item).link ? (item.itemlist||item).link : (item.itemlist||item).img 9 | li.reward-item 10 | img.post-qr-code__img(src=url_for((item.itemlist||item).img) alt=(item.itemlist||item).text onclick=`window.open('${url_for(clickTo)}')`) 11 | .post-qr-code__desc=(item.itemlist||item).text 12 | 13 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/rightside.pug: -------------------------------------------------------------------------------- 1 | section#rightside 2 | #rightside-config-hide 3 | if is_post() 4 | if theme.readmode 5 | button#readmode(type="button" title=_p('rightside.readmode_title')) 6 | i.fas.fa-book-open 7 | button#font_plus(type="button" title=_p('rightside.font_plus_title')) 8 | i.fas.fa-plus 9 | button#font_minus(type="button" title=_p('rightside.font_minus_title')) 10 | i.fas.fa-minus 11 | if theme.translate && theme.translate.enable 12 | button#translateLink(type="button" title=_p('rightside.translate_title'))= theme.translate.default 13 | if theme.darkmode.enable && theme.darkmode.button 14 | button#darkmode(type="button" title=_p('rightside.night_mode_title')) 15 | i.fas.fa-adjust 16 | #rightside-config-show 17 | button#rightside_config(type="button" title=_p("rightside.setting")) 18 | i.fas.fa-cog 19 | if is_post() && page.comments !== false && theme.comments.use 20 | a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment")) 21 | i.fas.fa-comments 22 | if showToc 23 | button#mobile-toc-button.close(type="button" title=_p("rightside.toc")) 24 | i.fas.fa-list-ul 25 | if theme.chat_btn && (theme.chatra.enable || theme.tidio.enable || theme.daovoice.enable || theme.gitter.enable) 26 | button#chat_btn(type="button" title=_p("rightside.chat_btn")) 27 | i.fas.fa-sms 28 | 29 | button#go-up(type="button" title=_p("rightside.back_to_top")) 30 | i.fas.fa-arrow-up 31 | 32 | 33 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/search/algolia.pug: -------------------------------------------------------------------------------- 1 | #algolia-search.search-dialog 2 | #algolia-search-title.search-dialog__title Algolia 3 | #algolia-input-panel 4 | #algolia-search-input 5 | hr 6 | #algolia-search-results 7 | #algolia-hits 8 | #algolia-pagination 9 | #algolia-stats 10 | span.search-close-button 11 | i.fas.fa-times 12 | .search-mask 13 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/search/index.pug: -------------------------------------------------------------------------------- 1 | if (theme.algolia_search.enable) 2 | include ./algolia.pug 3 | if (theme.local_search) 4 | if (!theme.algolia_search.enable && theme.local_search.enable) 5 | include ./local-search.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/search/local-search.pug: -------------------------------------------------------------------------------- 1 | #local-search.search-dialog 2 | #local-search-title.search-dialog__title=_p("local_search.label") 3 | #local-input-panel 4 | #local-search-input 5 | .local-search-box 6 | input(placeholder=_p("local_search.input_placeholder") type="text").local-search-box--input 7 | hr 8 | #local-search-results 9 | #local-hits 10 | #local-stats 11 | #hr.local-search-stats__hr 12 | case config.language 13 | when "zh-CN" 14 | span=_p("local_search.by") 15 | | #[a(href="https://github.com/wzpan/hexo-generator-search" style={'color': '#49B1F5'}) hexo-generator-search] 16 | | #[span=_p("local_search.powered")] 17 | when "en" 18 | default 19 | span=_p("local_search.powered_by") 20 | | #[a(href="https://github.com/wzpan/hexo-generator-search" style={'color': '#49B1F5'}) hexo-generator-search] 21 | span.search-close-button 22 | i.fas.fa-times 23 | .search-mask -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/share/add-this.pug: -------------------------------------------------------------------------------- 1 | .addthis_inline_share_toolbox 2 | script(src=`//s7.addthis.com/js/300/addthis_widget.js#pubid=${theme.addThis.pubid}` async) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/share/addtoany.pug: -------------------------------------------------------------------------------- 1 | .addtoany 2 | .a2a_kit.a2a_kit_size_32.a2a_default_style 3 | each name in theme.addtoany.item 4 | a(class="a2a_button_" + name) 5 | 6 | a.a2a_dd(href="https://www.addtoany.com/share") 7 | script(async src=url_for(theme.CDN.addtoany)) 8 | 9 | 10 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/share/index.pug: -------------------------------------------------------------------------------- 1 | .post_share 2 | if theme.addThis.enable 3 | include ./add-this.pug 4 | else if theme.sharejs && theme.sharejs.enable 5 | include ./share-js.pug 6 | else if theme.addtoany.enable 7 | include ./addtoany.pug 8 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/share/share-js.pug: -------------------------------------------------------------------------------- 1 | if (theme.sharejs && theme.sharejs.enable) 2 | .social-share(data-image=url_for(page.cover|| theme.avatar.img) data-sites= theme.sharejs.sites) 3 | link(rel="stylesheet" href=url_for(theme.CDN.sharejs_css)) 4 | script(src=url_for(theme.CDN.sharejs)) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/sidebar.pug: -------------------------------------------------------------------------------- 1 | - 2 | let tocNumber = page.toc_number !== undefined ? page.toc_number : theme.toc.number 3 | let autoOpenPostSet = page.auto_open == undefined ? theme.toc.auto_open : page.auto_open 4 | let autoOpenSidebar = autoOpenPostSet ? 'on' : '' 5 | - 6 | 7 | if(showToc) 8 | i.fas.fa-arrow-right#toggle-sidebar(class=autoOpenSidebar) 9 | #sidebar 10 | .sidebar-toc 11 | div.sidebar-toc__title= _p('sidebar.catalog') 12 | div.sidebar-toc__progress 13 | span.progress-notice= _p('sidebar.have_read') 14 | span.progress-num 0 15 | span.progress-percentage % 16 | div.sidebar-toc__progress-bar 17 | if (page.encrypt == true) 18 | div.sidebar-toc__content.toc-div-class(style="display:none")!=toc(page.origin, {list_number: tocNumber}) 19 | else 20 | div.sidebar-toc__content!=toc(page.content, {list_number: tocNumber}) 21 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/third-party/canvas-nest.pug: -------------------------------------------------------------------------------- 1 | script#canvas_nest(color=theme.canvas_nest.color opacity=theme.canvas_nest.opacity zIndex=theme.canvas_nest.zIndex count=theme.canvas_nest.count mobile=`${theme.canvas_nest.mobile}` src=url_for(theme.CDN.canvas_nest)) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/third-party/canvas-ribbon-piao.pug: -------------------------------------------------------------------------------- 1 | script(id="ribbon_piao" mobile=`${theme.canvas_ribbon_piao.mobile}` src=url_for(theme.CDN.canvas_ribbon_piao)) -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/third-party/canvas-ribbon.pug: -------------------------------------------------------------------------------- 1 | script(defer id="ribbon" src=url_for(theme.CDN.canvas_ribbon) size=theme.canvas_ribbon.size 2 | alpha=theme.canvas_ribbon.alpha zIndex=theme.canvas_ribbon.zIndex mobile=`${theme.canvas_ribbon.mobile}` data-click=`${theme.canvas_ribbon.click_to_change}`) 3 | 4 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/third-party/pangu.pug: -------------------------------------------------------------------------------- 1 | script(src=url_for(theme.CDN.pangu)) 2 | if theme.pangu.field === 'post' && is_post() 3 | script. 4 | document.addEventListener('DOMContentLoaded', function() { 5 | pangu.autoSpacingPage() 6 | }) 7 | else if theme.pangu.field === 'site' 8 | script. 9 | document.addEventListener('DOMContentLoaded', function() { 10 | pangu.autoSpacingPage() 11 | }) 12 | 13 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_ad.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-ad 2 | != theme.ad.aside 3 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_announcement.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-announcement 2 | .card-content 3 | .item-headline 4 | i.fas.fa-bullhorn.card-announcement-animation 5 | span= _p('aside.card_announcement') 6 | .announcement_content!= theme.aside.card_announcement.content -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_archives.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-archives 2 | .card-content 3 | .item-headline 4 | i.fas.fa-archive 5 | span= _p('aside.card_archives') 6 | 7 | - let type = theme.aside.card_archives.type || 'monthly' 8 | - let format = theme.aside.card_archives.format || 'MMMM YYYY' 9 | - let order = theme.aside.card_archives.order || -1 10 | - let limit = theme.aside.card_archives.limit === 0 ? 0 : theme.aside.card_archives.limit || 8 11 | != aside_archives({ type:type, format: format, order: order, limit: limit }) 12 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_author.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-info 2 | .card-content 3 | .card-info-avatar.is-center 4 | img.avatar-img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar") 5 | .author-info__name= config.author 6 | .author-info__description!= theme.aside.card_author.description || config.description 7 | 8 | .card-info-data 9 | if site.posts.length 10 | .card-info-data-item.is-center 11 | a(href=url_for(config.archive_dir)) 12 | .headline= _p('aside.articles') 13 | .length_num= site.posts.length 14 | 15 | if site.tags.length 16 | .card-info-data-item.is-center 17 | a(href=url_for(config.tag_dir)) 18 | .headline= _p('aside.tags') 19 | .length_num= site.tags.length 20 | 21 | if site.categories.length 22 | .card-info-data-item.is-center 23 | a(href=url_for(config.category_dir)) 24 | .headline= _p('aside.categories') 25 | .length_num= site.categories.length 26 | 27 | .card-info-bookmark.is-center 28 | button#bookmark-it.button--animated(type="button" title= _p('aside.card_bookmark')) 29 | i.fas.fa-bookmark 30 | span= _p('aside.card_bookmark') || 'Follow Me' 31 | 32 | if(theme.social) 33 | .card-info-social-icons.is-center 34 | !=fragment_cache('social', function(){return partial('includes/header/social')}) 35 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_calendar.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-calendar 2 | .card-content 3 | .item-headline 4 | i.far.fa-calendar-alt(aria-hidden="true") 5 | span= _p('aside.card_calendar') 6 | div.widget-wrap 7 | div#calendar.widget -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_categories.pug: -------------------------------------------------------------------------------- 1 | if site.categories.length 2 | .card-widget.card-categories 3 | .card-content 4 | .item-headline 5 | i.fas.fa-folder-open 6 | span= _p('aside.card_categories') 7 | !=aside_categories({ limit: theme.aside.card_categories.limit === 0 ? 0 : theme.aside.card_categories.limit || 8 , expand: theme.aside.card_categories.expand }) 8 | 9 | 10 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_map.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-map 2 | .card-content 3 | .item-headline 4 | i.fa.fa-globe-asia(aria-hidden="true") 5 | span= _p('aside.card_map') 6 | //- 下面这行适用于3D地图(Globe Widget) 7 | script#clstr_globe(type="text/javascript" defer="defer" src="//cdn.clustrmaps.com/globe.js?d=fVQb75D6mjY-w9gWhFtj294byIhuYzIJLyUZYhnjYSo") -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_pixiv.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-pixiv 2 | .card-content 3 | .item-headline 4 | i.fa.fa-image(aria-hidden="true") 5 | span= _p('aside.card_pixiv') 6 | iframe(src="https://cloud.mokeyjay.com/pixiv" frameborder="0" style="width:99%;height:380px;margin:0;") -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_recent_post.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-recent-post 2 | .card-content 3 | .item-headline 4 | i.fas.fa-history 5 | span= _p('aside.card_recent_post') 6 | .aside-recent-item 7 | - var postLimit = theme.aside.card_recent_post.limit === 0 ? site.posts.length : theme.aside.card_recent_post.limit || 5 8 | - site.posts.sort('date', -1).limit(postLimit).each(function(article){ 9 | .aside-recent-post 10 | - var link = article.link || article.path 11 | - var title = article.title || _p('no_title') 12 | - var no_cover = article.cover === false || !theme.cover.aside_enable ? 'no-aside-cover' : '' 13 | - var post_cover = article.cover 14 | 15 | a(href=url_for(link)) 16 | if post_cover && theme.cover.aside_enable 17 | .aside-post-cover 18 | if theme.lazyload.enable 19 | img.aside-post-bg(data-src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` title=title alt=title) 20 | else 21 | img.aside-post-bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` title=title alt=title) 22 | .aside-post-title(class=no_cover) 23 | .aside-post_title(href=url_for(link) title=article.title || _p('no_title'))= article.title || _p('no_title') 24 | time.aside-post_meta.post-meta__date(title=_p('post.created') + ' ' + full_date(article.date)) #[=date(article.date, config.date_format)] 25 | 26 | - }) 27 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_tags.pug: -------------------------------------------------------------------------------- 1 | if site.tags.length 2 | .card-widget.card-tags 3 | .card-content 4 | .item-headline 5 | i.fas.fa-tags 6 | span= _p('aside.card_tags') 7 | 8 | - let tagLimit = theme.aside.card_tags.limit === 0 ? 0 : theme.aside.card_tags.limit || 40 9 | if theme.aside.card_tags.color 10 | .card-tag-cloud!=cloudTags({source: site.tags, minfontsize: 16, maxfontsize: 22, limit: tagLimit}) 11 | else 12 | .card-tag-cloud!= tagcloud({min_font: 16, max_font: 22, amount: tagLimit , color: true, start_color: '#999', end_color: '#99a9bf'}) 13 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/card_webinfo.pug: -------------------------------------------------------------------------------- 1 | .card-widget.card-webinfo 2 | .card-content 3 | .item-headline 4 | i.fas.fa-chart-line 5 | span= _p('aside.card_webinfo.headline') 6 | .webinfo 7 | .webinfo-item 8 | .webinfo-article-name= _p('aside.card_webinfo.article_name') + " :" 9 | .webinfo-article-count= site.posts.length 10 | if theme.runtimeshow.enable 11 | .webinfo-item 12 | .webinfo-runtime-name= _p('aside.card_webinfo.runtime_name') + " :" 13 | #webinfo-runtime-count.webinfo-runtime-count(publish_date=theme.runtimeshow.publish_date) 14 | if theme.wordcount.enable && theme.wordcount.total_wordcount 15 | .webinfo-item 16 | .webinfo-site-wordcount-name=_p('aside.card_webinfo.site_wordcount') + " :" 17 | .webinfo-site-wordcount=totalcount(site) 18 | if theme.busuanzi.site_uv 19 | .webinfo-item 20 | .webinfo-site-uv-name= _p('aside.card_webinfo.site_uv_name') + " :" 21 | .webinfo-site-uv-count#busuanzi_value_site_uv 22 | if theme.busuanzi.site_pv 23 | .webinfo-item 24 | .webinfo-site-name= _p('aside.card_webinfo.site_pv_name') + " :" 25 | .webinfo-site-pv-count#busuanzi_value_site_pv 26 | 27 | -------------------------------------------------------------------------------- /themes/Butterfly/layout/includes/widget/index.pug: -------------------------------------------------------------------------------- 1 | if theme.aside.enable 2 | if page.aside !== false 3 | #aside_content.aside_content 4 | if theme.aside.card_author.enable 5 | !=partial('includes/widget/card_author', {}, {cache:theme.fragment_cache}) 6 | if theme.aside.card_announcement.enable 7 | !=partial('includes/widget/card_announcement', {}, {cache:theme.fragment_cache}) 8 | if theme.aside.card_pixiv.enable 9 | !=partial('includes/widget/card_pixiv', {}, {cache:theme.fragment_cache}) 10 | if theme.aside.card_calendar.enable 11 | !=partial('includes/widget/card_calendar', {}, {cache:theme.fragment_cache}) 12 | if theme.aside.card_map.enable 13 | !=partial('includes/widget/card_map', {}, {cache:theme.fragment_cache}) 14 | if theme.aside.card_recent_post.enable 15 | !=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache}) 16 | if theme.ad && theme.ad.aside 17 | !=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache}) 18 | if theme.aside.card_categories.enable 19 | !=partial('includes/widget/card_categories', {}, {cache:theme.fragment_cache}) 20 | if theme.aside.card_tags.enable 21 | !=partial('includes/widget/card_tags', {}, {cache:theme.fragment_cache}) 22 | if theme.aside.card_archives.enable 23 | !=partial('includes/widget/card_archives', {}, {cache:theme.fragment_cache}) 24 | if theme.aside.card_webinfo 25 | !=partial('includes/widget/card_webinfo', {}, {cache:theme.fragment_cache}) -------------------------------------------------------------------------------- /themes/Butterfly/layout/index.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | include ./includes/mixins/post-ui.pug 5 | #recent-posts.recent-posts 6 | +postUI 7 | include includes/pagination.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/page.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | if page.type === 'tags' 5 | .tag-cloud 6 | .tag-cloud__title= _p('page.tag') 7 | | - 8 | span.tag-cloud__amount= site.tags.length 9 | .tag-cloud-tags 10 | !=cloudTags({source: site.tags, minfontsize: 15, maxfontsize: 30, limit: 0}) 11 | if page.comments !== false 12 | include includes/comments/index.pug 13 | else if page.type === 'link' 14 | include flink.pug 15 | else if page.type === 'categories' 16 | .category-content 17 | .category-lists 18 | .category__title= _p('page.category') 19 | | - 20 | span.category__amount= site.categories.length 21 | div!= list_categories() 22 | if page.comments !== false 23 | include includes/comments/index.pug 24 | else 25 | #page 26 | #article-container!= page.content 27 | if page.comments !== false 28 | include includes/comments/index.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/post.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | article#post(class="") 5 | #article-container.post-content!=page.content 6 | include includes/post/post-copyright.pug 7 | .tag_share 8 | if (theme.post_meta.post.tags) 9 | .post-meta__tag-list 10 | each item, index in page.tags.data 11 | a(href=url_for(item.path)).post-meta__tags #[=item.name] 12 | !=partial('includes/share/index', {}, {cache:theme.fragment_cache}) 13 | 14 | if theme.reward.enable 15 | !=partial('includes/post/reward', {}, {cache:theme.fragment_cache}) 16 | 17 | //- ad 18 | if theme.ad && theme.ad.post 19 | .post-ad!=theme.ad.post 20 | 21 | include includes/pagination.pug 22 | if theme.related_post && theme.related_post.enable 23 | != related_posts(page,site.posts) 24 | if page.comments !== false 25 | include includes/comments/index.pug -------------------------------------------------------------------------------- /themes/Butterfly/layout/tag.pug: -------------------------------------------------------------------------------- 1 | extends includes/layout.pug 2 | 3 | block content 4 | if theme.tag_ui == 'index' 5 | include ./includes/mixins/post-ui.pug 6 | #recent-posts.recent-posts 7 | +postUI 8 | include includes/pagination.pug 9 | else 10 | include ./includes/mixins/article-sort.pug 11 | #tag 12 | .article-sort-title= _p('page.tag') + ' - ' + page.tag 13 | +articleSort(page.posts) 14 | include includes/pagination.pug -------------------------------------------------------------------------------- /themes/Butterfly/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-theme-butterfly", 3 | "version": "3.0.0", 4 | "private": true, 5 | "engines": { 6 | "node": ">=8.10.0" 7 | }, 8 | "description": "A Simple and Card UI Design theme for Hexo", 9 | "keywords": [ 10 | "hexo", 11 | "theme", 12 | "butterfly", 13 | "Card UI Design" 14 | ], 15 | "repository": "https://github.com/jerryc127/hexo-theme-butterfly.git", 16 | "author": "Jerry ", 17 | "license": "MIT" 18 | } -------------------------------------------------------------------------------- /themes/Butterfly/scripts/events/404.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * 404 error page 4 | */ 5 | 6 | 'use strict' 7 | 8 | hexo.extend.generator.register('404', function (locals) { 9 | if (!hexo.theme.config.error_404.enable) return 10 | return { 11 | path: '404.html', 12 | data: locals.posts, 13 | layout: ['404'] 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /themes/Butterfly/scripts/events/replace_config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Note: configs in _data/butterfly.yml will replace configs in hexo.theme.config. 3 | */ 4 | 5 | 'use strict' 6 | 7 | hexo.on('generateBefore', function () { 8 | const rootConfig = hexo.config 9 | if (hexo.locals.get) { 10 | const data = hexo.locals.get('data') 11 | data && data.butterfly && (hexo.theme.config = data.butterfly) 12 | } 13 | hexo.theme.config.rootConfig = rootConfig 14 | }) 15 | -------------------------------------------------------------------------------- /themes/Butterfly/scripts/filters/post_lazyload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * lazyload 4 | * replace src to data-src 5 | */ 6 | //
7 | 8 | 'use strict' 9 | 10 | const urlFor = require('hexo-util').url_for.bind(hexo) 11 | 12 | function lazyProcess (htmlContent) { 13 | const bg = hexo.theme.config.lazyload.post ? urlFor(hexo.theme.config.lazyload.post) : 'data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=' 14 | return htmlContent.replace(/( yearA === yearB && monthA === monthB 20 | : (yearA, monthA, yearB, monthB) => yearA === yearB 21 | const limit = options.limit 22 | const moreButton = this._p('aside.more_button') 23 | let result = '' 24 | 25 | if (!format) { 26 | format = type === 'monthly' ? 'MMMM YYYY' : 'YYYY' 27 | } 28 | 29 | const posts = this.site.posts.sort('date', order) 30 | if (!posts.length) return result 31 | 32 | const data = [] 33 | let length = 0 34 | 35 | posts.forEach(post => { 36 | // Clone the date object to avoid pollution 37 | let date = post.date.clone() 38 | 39 | if (timezone) date = date.tz(timezone) 40 | 41 | const year = date.year() 42 | const month = date.month() + 1 43 | const lastData = data[length - 1] 44 | 45 | if (!lastData || !compareFunc(lastData.year, lastData.month, year, month)) { 46 | if (lang) date = date.locale(lang) 47 | const name = date.format(format) 48 | length = data.push({ 49 | name, 50 | year, 51 | month, 52 | count: 1 53 | }) 54 | } else { 55 | lastData.count++ 56 | } 57 | }) 58 | 59 | const link = item => { 60 | let url = `${archiveDir}/${item.year}/` 61 | 62 | if (type === 'monthly') { 63 | if (item.month < 10) url += '0' 64 | url += `${item.month}/` 65 | } 66 | 67 | return this.url_for(url) 68 | } 69 | 70 | result += '' 98 | return result 99 | }) 100 | 101 | const toMomentLocale = function (lang) { 102 | if (lang === undefined) { 103 | return undefined 104 | } 105 | 106 | // moment.locale('') equals moment.locale('en') 107 | // moment.locale(null) equals moment.locale('en') 108 | if (!lang || lang === 'en' || lang === 'default') { 109 | return 'en' 110 | } 111 | return lang.toLowerCase().replace('_', '-') 112 | } 113 | -------------------------------------------------------------------------------- /themes/Butterfly/scripts/helpers/aside_categories.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * for aside categories 4 | */ 5 | 6 | 'use strict' 7 | 8 | hexo.extend.helper.register('aside_categories', function (categories, options) { 9 | if (!options && (!categories || !Object.prototype.hasOwnProperty.call(categories, 'length')) 10 | ) { 11 | options = categories 12 | categories = this.site.categories 13 | } 14 | 15 | if (!categories || !categories.length) return '' 16 | options = options || {} 17 | const { config } = this 18 | const showCount = Object.prototype.hasOwnProperty.call(options, 'show_count') 19 | ? options.show_count 20 | : true 21 | const depth = options.depth ? parseInt(options.depth, 10) : 0 22 | const orderby = options.orderby || 'name' 23 | const order = options.order || 1 24 | const categoryDir = this.url_for(config.category_dir) 25 | const limit = options.limit === 0 ? categories.length : options.limit 26 | const isExpand = options.expand !== 'none' 27 | const expandClass = isExpand && options.expand === true ? 'card-category-list-icon expand' : 'card-category-list-icon' 28 | 29 | const buttonLabel = this._p('aside.more_button') 30 | const prepareQuery = (parent) => { 31 | const query = {} 32 | if (parent) { query.parent = parent } else { query.parent = { $exists: false } } 33 | return categories.find(query).sort(orderby, order).filter((cat) => cat.length) 34 | } 35 | 36 | const hierarchicalList = (t, level, parent, topparent = true) => { 37 | let result = '' 38 | const isTopParent = topparent 39 | if (t > 0) { 40 | prepareQuery(parent).forEach((cat, i) => { 41 | if (t > 0) { 42 | t = t - 1 43 | let child 44 | if (!depth || level + 1 < depth) { 45 | const childList = hierarchicalList(t, level + 1, cat._id, false) 46 | child = childList[0] 47 | t = childList[1] 48 | } 49 | 50 | const parentClass = isExpand && isTopParent && child ? 'parent' : '' 51 | 52 | result += `
  • ` 53 | 54 | result += `` 55 | 56 | result += `${cat.name}` 57 | 58 | if (showCount) { 59 | result += `${cat.length}` 60 | } 61 | 62 | if (isExpand && isTopParent && child) { 63 | result += `` 64 | } 65 | 66 | result += '' 67 | 68 | result += '
  • ' 69 | 70 | if (child) { 71 | result += `
      ${child}
    ` 72 | } 73 | } 74 | }) 75 | } 76 | 77 | return [result, t] 78 | } 79 | 80 | const list = hierarchicalList(limit, 0) 81 | 82 | const moreButton = function () { 83 | let moreHtml = '' 84 | if (categories.length <= limit) return '' 85 | moreHtml += '
  • ' 86 | moreHtml += ` 87 | ${buttonLabel}
  • ` 88 | 89 | return moreHtml 90 | } 91 | 92 | return `
      93 | ${list[0]} 94 | ${moreButton()} 95 |
    ` 96 | }) 97 | -------------------------------------------------------------------------------- /themes/Butterfly/scripts/helpers/page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * @example 4 | * page_description() 5 | * injectHtml(data) 6 | * cloudTags(source, minfontsize, maxfontsize, limit) 7 | */ 8 | 9 | 'use strict' 10 | 11 | const { stripHTML, escapeHTML } = require('hexo-util') 12 | 13 | hexo.extend.helper.register('page_description', function () { 14 | const { config, page } = this 15 | let description = page.description || page.content || page.title || config.description 16 | 17 | if (description) { 18 | description = escapeHTML(stripHTML(description).substring(0, 200) 19 | .trim() 20 | ).replace(/\n/g, ' ') 21 | return description 22 | } 23 | }) 24 | 25 | hexo.extend.helper.register('injectHtml', function (data) { 26 | let result = '' 27 | if (!data) return '' 28 | for (let i = 0; i < data.length; i++) { 29 | result += data[i] 30 | } 31 | return result 32 | }) 33 | 34 | hexo.extend.helper.register('cloudTags', function (options = {}) { 35 | const env = this 36 | const source = options.source 37 | const minfontsize = options.minfontsize 38 | const maxfontsize = options.maxfontsize 39 | const limit = options.limit 40 | 41 | let result = '' 42 | const tagLimit = limit === 0 ? source.length : limit 43 | source.sort('name').limit(tagLimit).forEach(function (tags) { 44 | const fontSize = Math.floor(Math.random() * (maxfontsize - minfontsize) + minfontsize) + 'px' 45 | const color = 'rgb(' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ')' // 0,0,0 -> 200,200,200 46 | result += `${tags.name}` 47 | }) 48 | return result 49 | }) 50 | 51 | hexo.extend.helper.register('urlNoIndex', function () { 52 | const { permalink } = hexo.config 53 | let url = this.url.replace(/index\.html$/, '') 54 | if (!permalink.endsWith('.html')) { 55 | url = url.replace(/\.html$/, '') 56 | } 57 | return url 58 | }) 59 | -------------------------------------------------------------------------------- /themes/Butterfly/scripts/helpers/related_post.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Butterfly 3 | * Related Posts 4 | * According the tag 5 | */ 6 | 7 | 'use strict' 8 | 9 | hexo.extend.helper.register('related_posts', function (currentPost, allPosts) { 10 | let relatedPosts = [] 11 | currentPost.tags.forEach(function (tag) { 12 | allPosts.forEach(function (post) { 13 | if (isTagRelated(tag.name, post.tags)) { 14 | const relatedPost = { 15 | title: post.title, 16 | path: post.path, 17 | cover: post.cover, 18 | randomcover: post.randomcover, 19 | weight: 1, 20 | updated: post.updated, 21 | created: post.date 22 | } 23 | const index = findItem(relatedPosts, 'path', post.path) 24 | if (index !== -1) { 25 | relatedPosts[index].weight += 1 26 | } else { 27 | if (currentPost.path !== post.path) { 28 | relatedPosts.push(relatedPost) 29 | } 30 | } 31 | } 32 | }) 33 | }) 34 | if (relatedPosts.length === 0) { 35 | return '' 36 | } 37 | let result = '' 38 | const hexoConfig = hexo.theme.config.rootConfig 39 | const config = hexo.theme.config 40 | 41 | const limitNum = config.related_post.limit || 6 42 | const dateType = config.related_post.date_type || 'created' 43 | const headlineLang = this._p('post.recommend') 44 | const lazySrc = config.lazyload.enable ? 'data-src' : 'src' 45 | 46 | relatedPosts = relatedPosts.sort(compare('weight')) 47 | 48 | if (relatedPosts.length > 0) { 49 | result += '