精华内容
下载资源
问答
  • 相信大家都或多或少的都接触过gitbookgitbook 首先是一个软件,正如上面定义的那样,它使用 Git 和 Markdown 来编排书本,如果用户没有听过 Git 和 Markdown,那么 gitbook 可能不适合你。废话不多说,干起来。 1 ...
    相信大家都或多或少的都接触过gitbook。gitbook 首先是一个软件,正如上面定义的那样,它使用 Git 和 Markdown 来编排书本,如果用户没有听过 Git 和 Markdown,那么 gitbook 可能不适合你。废话不多说,干起来。

    1 gitbook安装

    1.1 安装npm包

      $ npm install gitbook -g

    1.2 初始化项目

      $ mkdir gitbook 新建目录
      $ cd gitbook
      $ gitbook init
      
      目录
      gitbook/
      ├── README.md
      └── SUMMARY.md

    1.3 起服务

      $ gitbook serve

    1.4 打开浏览器

    可以用浏览器打开 http://127.0.0.1:4000

    1.5 生产文件

      $ gitbook build

    2 登录权限认证

    搭建就完成了,但是有一下内部文档,不想公布出去,怎么办,这个网上没有答案,但是方法总是有的,那就是nginx

    2.1 用到nginx认证模块

    server {
       listen 80;
       server_name www.host.com ;             # 域名注意不要加协议
       location / {
       root  html/blog;                        #根  静态文件目录
       index index.html index.htm;
       auth_basic     "pleas you password";    # nginx 认证用户和密码
       auth_basic_user_file htpasswd;          # nginx认证文件目录  可以随意指定 
    }

    2.2 因为要用到密码,而且是加密的,所有引入httpd模块

      $ yum -y install httpd  
      $ htpasswd -bc /applocation/nginx/conf/htpasswd qiyun 123456  #生产密码文件,如果不能写入,就创建好文件,在执行命令

    2.3 重新检测

      $ nginx -t

    2.4 重启

      $ nginx -S reload
    

    3 案例

    url: http://gitbook.beastxw.wang/

    name: aaa

    pwd: 123

    4 图片

    gitbook
    clipboard.png

    登录认证
    clipboard.png

    5 博客

    url: http://blog.beastxw.wang/2019...

    展开全文
  • vue权限管理系统

    千次阅读 2019-01-17 19:54:23
    vue权限系统 后台管理系统一般都会有权限模块,用来控制用户能访问哪些页面和哪些数据接口。大多数管理系统的页面都长这样。 左边为菜单,分为两级,右边为图表显示区域,有增删改查的按钮。 表的结构 SET NAMES ...

    vue权限系统

    后台管理系统一般都会有权限模块,用来控制用户能访问哪些页面和哪些数据接口。大多数管理系统的页面都长这样。

    image

    左边为菜单,分为两级,右边为图表显示区域,有增删改查的按钮。

    表的结构

    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for t_auth_rule
    -- ----------------------------
    DROP TABLE IF EXISTS `t_auth_rule`;
    CREATE TABLE `t_auth_rule` (
      `id_pk` bigint(20) NOT NULL AUTO_INCREMENT,
      `auth_id` varchar(128) NOT NULL COMMENT '权限Id',
      `pauth_id` varchar(128) DEFAULT NULL COMMENT '父级Id',
      `auth_name` varchar(255) NOT NULL COMMENT '权限名称',
      `auth_icon` varchar(255) NOT NULL COMMENT '权限图标',
      `auth_type` smallint(6) NOT NULL COMMENT '权限类型,BIT表示其属性\r\n            0x00表示可显示的菜单权限节点;\r\n            0x01表示普通节点',
      `auth_condition` text COMMENT '条件',
      `remark` varchar(255) DEFAULT NULL COMMENT '备注',
      `is_menu` smallint(255) DEFAULT '0' COMMENT '是否为菜单,0表示非,1表示是',
      `weight` int(11) NOT NULL DEFAULT '0' COMMENT '权重',
      `rule` varchar(256) DEFAULT NULL COMMENT '规则路径主要对应菜单或方法的路径名称',
      `cr_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `up_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      PRIMARY KEY (`id_pk`),
      UNIQUE KEY `AK_auth_id` (`auth_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=264 DEFAULT CHARSET=utf8 COMMENT='权限规则表,记录权限相关的信息,权限以父子关系存在,菜单是权限的一种。';
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for t_role_auth
    -- ----------------------------
    DROP TABLE IF EXISTS `t_role_auth`;
    CREATE TABLE `t_role_auth` (
      `id_pk` bigint(20) NOT NULL AUTO_INCREMENT,
      `role_id_fk` varchar(32) DEFAULT NULL COMMENT '角色id',
      `auth_id_fk` varchar(128) DEFAULT NULL COMMENT '权限id',
      `aa` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id_pk`)
    ) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8 COMMENT='角色与权限的关系表';
    
    SET FOREIGN_KEY_CHECKS = 1;

    稍微解释一下表结构,t_auth_rule 表用来存储对应的权限菜单,一般来说,菜单分为一级和二级菜单,rule字段对应前端的路由规则;而按钮为第三级,rule对应的是接口url地址。
    t_role_auth 表为角色权限关联表,一个角色拥有哪些权限是通过这张表查出来的。当然还有一个role表,还有一个账号表,账号表里有一个role的外键。
    这样就是一个账号 --> 角色 --> 权限的关系。

    对于菜单的权限,通过路由表匹配

    addRouters(menuMap) {
        let routerArr = [];
        for (let j = 0; j < routerList.length; j++) {
            let obj;
            if (menuMap['AuthRule::' + routerList[j].path]) {     // 找到一级菜单
                obj = {
                    path: routerList[j].path,
                    component: routerList[j].component,
                    redirect: routerList[j].redirect,
                    name: routerList[j].name,
                    meta: routerList[j].meta,
                    children: []
                };
    
                if (routerList[j].children.length) {
                    for (let k = 0; k < routerList[j].children.length; k++) {
                        let _fullpath = routerList[j].children[k].path
                        if (routerList[j].children[k].meta) {
                            _fullpath = routerList[j].children[k].meta.parentPath + '/' + _fullpath 
                        }
                        if (menuMap['AuthRule::' + _fullpath]) {  // 找到二级菜单
                            obj.children.push(routerList[j].children[k]);
                        }
                    }
                }
            }
            if (obj) {
                routerArr.push(obj);
                this.$router.options.routes.push(obj);
            }
        }
    
        storage.set("routerArr", routerArr);
        this.$router.addRoutes(routerArr);
        this.$router.push({ path: "/" });
    },

    menuMap为登录时获取的权限菜单,是一个对象; routerList为前端定义的路由表;遍历routerList,如果routerList的key在menuMap里能找到的话,就表示该路由存在。最后生成一个过滤后的路由表,用vue提供的addRoutes方法动态添加到路由中,并把过滤后的路由表存到本地。

    const menuMap = {
        '/dashboard': {path: '/dashboard', name: '首页'}
    }
    const routerList = [
        {path: '/dashboard', name: '首页', component: ..}
    ]

    在页面刷新的时候,从本地获取路由表,添加到路由表中,代码如下,constRouterArr为基础路由表,比如登录,404等

    注意这一步有个问题,由于我写的storage库用了JSON.stringify,把路由表中的component(实际为一个函数)丢失了,所以在从本地获取路由的时候,还要重新生成一个新的路由表,重新把component加上去,即把上面的addrouters重新执行一遍

    ~~const routerList = storage.get('routerArr')
    const routerArr = constRouterArr.concat(routerList);~~

    export function getRouterList() {
      if (!sessionStorage.getItem('user_info')) {
        storage.set('menuTree', ''); // 清空菜单权限数据
        storage.set('routerArr', ''); 
      }
        let menuMap = storage.get('menuTree') ? storage.get('menuTree') : [];
        
        let routerArr = [];
        for (let j = 0; j < routerList.length; j++) {
            let obj;
            if (menuMap['AuthRule::' + routerList[j].path]) {  // 找到一级菜单
                // console.log(routerList[j].component)
                obj = {
                    path: routerList[j].path,
                    component: routerList[j].component,  // 从本地获取的数据被丢失了,需要重新组装
                    redirect: routerList[j].redirect,
                    name: routerList[j].name,
                    meta: routerList[j].meta,
                    children: []
                };
                // console.log(routerList[j].children, routerList[j])
                if (routerList[j].children && routerList[j].children.length) {
                    for (let k = 0; k < routerList[j].children.length; k++) {
                        let _fullpath = routerList[j].children[k].path
                        if (routerList[j].children[k].meta) {
                            _fullpath = routerList[j].children[k].meta.parentPath + '/' + _fullpath 
                        }
                        if (menuMap['AuthRule::' + _fullpath]) {  // 找到二级菜单
                            obj.children.push(routerList[j].children[k]);
                        }
                    }
                }
            }
            if (obj) {
                routerArr.push(obj);
            }
        }
        
      return routerArr; 
    }

    对于按钮的权限

    if (res.data.auth_rule_map) {
        let obj = {}
        Object.keys(res.data.auth_rule_map).forEach(i => {
          // 将所有的按钮放到一个obj里 key 为接口地址  
          if (res.data.auth_rule_map[i].is_menu === 0) {  // 如果是按钮
            obj[res.data.auth_rule_map[i].rule] = 1
          }             
        })
        storage.set("btnList", obj);
        storage.set("menuTree", res.data.auth_rule_map);
    }

    auth_rule_map为接口返回权限map,把按钮的权限过滤出来存到本地
    将map添加到每个路由组件的data里,(这里有一个问题,怎么判断一个组件是否是路由组件),目前想到的是通过组件name来判断,把所有的路由组件放到一个数组里做判断。

    在组件内部的按钮上加上v-if,如果this.uri__里的uri在uriMap里存在就显示。
    也可以通过方法来判断,如下面的__isBtnShow,不仅可以控制按钮的显示隐藏,还可以控制其样式,比如颜色等,更加灵活,推荐使用方法来控制

    uri = {
        ADD_MEMBER: '/api/add_member'
    }
    
    export default function install (Vue) {
      const uriMap = storage.get('btnList')
      //uriMap['/admin/api/auth_rule/update_auth_rule.action'] = 1
      Vue.mixin({
        created() {
          const arr = ['MemberManage', 'PayManage', '...']
          if (arr.indexOf(this.$options.name) !== -1) {
            this.dataUri__ = uriMap
            this.uri__ = uri  
          }
        },
        data() {
          return {
            dataUri__: {}
          }
        },
        methods: {
          __isBtnShow(uri) {
            return uriMap[uri] ? 'display: inline-block' : 'display: none'
          },
        }
      })
    }
    
    <Button v-if="dataUri__[uri__.ADD_MEMBER]">添加会员</Button>
    
    // 通过方法来控制,更加灵活
    <Button :style="__isBtnShow(uri__.ADD_MEMBER)">添加会员</Button>

    登出的问题

    登出后要清空缓存,routerArr,btnList 等。
    由于之前登录,调用addRouter把权限上个账号的路由表加进去了,所以登出后要location.reload()一次,重新实例化路由表,去掉动态添加的路由,只保留基础路由。
    location.reload()体验不是太好,但是vue-router没有提供动态删除路由的api,比如 deleteRouter。

    同时登两个账号,导致刷新页面的时候,前者页面的本地缓存被覆盖,权限菜单等数据发生变化,路由表也发生变化

    能想到的解决方法是存一个loginIndex 来表示登录账号的个数,比如第一次登录的时候存一个loginIndex=0, 后面存数据的时候都把这个参数带上;后面登多个账号的时候个loginIndex++,这样localStorage的key就是一个动态的(这样还是不行)
    最简单的方法是存到localStorage里,只有登出才会清空缓存,只能登一个账号。

    展开全文
  • ubuntu下安装gitbook并生成电子书

    千次阅读 2018-09-12 10:55:21
     由于 GitBook 是基于 Node.js 开发的,所以依赖 Node.js 环境。如果您的系统中还未安装 Node.js,去官网下载nodejs,根据你所使用的系统下载对应的版本。如果已安装则略过本步骤。  解压到software文件夹: ...

    一、安装 Node.js

            由于 GitBook 是基于 Node.js 开发的,所以依赖 Node.js 环境。如果您的系统中还未安装 Node.js,去官网下载nodejs,根据你所使用的系统下载对应的版本。如果已安装则略过本步骤。

            解压到software文件夹:

            在bin目录下就有了node,npm,npx三个文件,进入bin文件夹,输入以下命令

            想要在任何目录下都能运行,只需要建立符号链接到/usr/local/bin下就行了 
            注意符号链接 写成绝对路径,不要用相对路径

    sudo ln -s /home/gz/software/node-v8.12.0-linux-x86/bin/node /usr/local/bin/node
    sudo ln -s /home/gz/software/node-v8.12.0-linux-x86/bin/npm /usr/local/bin/npm
    

    二、安装 GitBook

            gitbook Ubuntu下,在安装好nodejs后直接使用如下命令安装,依据自己安装的目录可能有权限问题,自行加上

    npm install -g gitbook-cli

            由于网络的原因,安装的时间可能会较长一些,请耐心等待直到安装完成。安装完成后,同样的在bin目录下(其他路径不能运行)设置一个符号链接。 

    sudo ln -s /home/gz/software/node-v8.12.0-linux-x86/bin/gitbook /usr/local/bin/gitbook

            然后查看gitbook版本,检查是否安装成功。

    gitbook -V #查看gitbook版本

    三、创建电子书项目

            新建一个目录,并进入该目录使用 gitbook 命令初始化电子书项目。举个例子,现在要创建一个名为“MyFirstBook”的空白电子书项目,如下所示:

    mkdir MyFirstBook
    cd MyFirstBook
    gitbook init

    四、编辑电子书内容

            初始化后的目录中会出现“README.md(电子书简介文件)”和“SUMMARY.md(导航目录文件)”两个基本文件。除此之外还可以手动新建其它“Glossary.md(书尾的词汇表)”、“book.json(电子书配置文件)”。电子书的正文内容可以根据自己的喜好创建新的后缀为 .md 文件,如“chapter01.md”,然后用 MarkDown 编写具体的文本内容即可。下面对这些文件分别做详细介绍。

    1、README.md

            此文件是简单的电子书介绍,可以把您所制作的电子书做一下简单的描述:

    # 简介
    
    这是我的第一本使用 GitBook 制作的电子书。

    2、SUMMARY.md

            此为电子书的导航目录文件,每当新增一个章节文件就需要向此文件中添加一条记录。对于 Kindle 电子书来说,此文件所呈现的目录结构就是开头的目录内容和“前往”的目录导航。

    # Summary
    
    * [简介](README.md)
    * [第一章](section1/README.md)
    * [第二章](section2/README.md)

            如果需要“子章节”可以使用 Tab 缩进来实现(最多支持三级标题),如下所示:

    # Summary
    
    * [第一章](section1/README.md)
        * [第一节](section1/example1.md)
        * [第二节](section1/example2.md)
    * [第二章](section2/README.md)
        * [第一节](section2/example1.md)

    3、Glossary.md

            对于电子书内容中需要解释的词汇可在此文件中定义。词汇表会被放在电子书末尾。其格式如下所示:

    # 电子书
    电子书是指将文字、图片、声音、影像等讯息内容数字化的出版物和植入或下载数字化文字、图片、声音、影像等讯息内容的集存储和显示终端于一体的手持阅读器。
    
    # Kindle
    Amazon Kindle 是由 Amazon 设计和销售的电子书阅读器(以及软件平台)。用户可以通过无线网络使用 Amazon Kindle 购买、下载和阅读电子书、报纸、杂志、博客及其他电子媒体。

    4、book.json

            “book.json”是电子书的配置文件,可以看作是电子书的“原数据”,比如 title、description、isbn、language、direction、styles 等。它的基本结构如下所示:

    {
        "title": "我的第一本電子書",
        "description": "用 GitBook 制作的第一本電子書!",
        "isbn": "978-3-16-148410-0",
        "language": "zh-tw",
        "direction": "ltr"
    }

    5、普通章节.md 文件

            普通章节.md 文件可以使用您感觉顺手的文本编辑器编写。MarkDown 的写法可以查看相关示例。每编写一个 .md 文件,不要忘了在“SUMMARY.md”文件中添加一条记录哦。

    6、电子书封面图片

            GitBook 帮助文档建议封面图片的尺寸为 1800*2360 像素并且遵循建议:

    • 没有边框
    • 清晰可见的书本标题
    • 任何重要的文字在小版本中应该可见

            图片的格式为 jpg 格式。把图片重命名为“cover.jpg”放到电子书项目文件夹即可。

    五、预览电子书内容

            电子书内容编写完毕后可以使用浏览器预览一下。先输入下面的命令据 .md 文件生成 HTML 文档:

    $ gitbook build

            生成完毕后,会在电子书项目目录中出现一个名为“_book”的文件夹。进入该文件夹,直接用浏览器打开“index.html”,或先输入下面的命令:

    $ gitbook serve

            然后在浏览器中输入“http://localhost:4000”即可预览电子书内容,预览完毕后按 Ctrl + C 结束。

    六、生成电子书文件

            确定电子书没有问题后,可以通过输入以下命令生成 mobi 电子书:

    $ gitbook mobi ./ ./MyFirstBook.mobi

            如果出现错误,说明还未安装Calibre。

            运行安装脚本:

    sudo -v && wget -nv -O- https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py | sudo python -c "import sys; main=lambda:sys.stderr.write('Download failed\n'); exec(sys.stdin.read()); main()"

            运行Calibre:

    $ calibre

            再次运行转换命令,即可生成 mobi 格式电子书。

            大 功 告 成!!!

    展开全文
  • Gitbook 是一款产品文档...可能是网上关于 Gitbook 的教程相对来说有些落后,加上写文章时分享了不少关于 gitbook 系列教程,因此关注我的粉丝好友中有不少是来源于 Gitbook. 所以上个月有个好友问我能不能配置 Gitbo...

    Gitbook 是一款产品文档构建工具,也可以用于构建个人博客,默认情况下电脑端访问时左侧菜单是展开状态,可偏偏有人想要实现默认折叠效果,于是诞生了这篇文章!

    善良的我选择帮助别人

    可能是网上关于 Gitbook 的教程相对来说有些落后,加上写文章时分享了不少关于 gitbook 系列教程,因此关注我的粉丝好友中有不少是来源于 Gitbook.

    所以上个月有个好友问我能不能配置 Gitbook 默认折叠的效果,心里有些犯难,作为 gitbook 的忠实粉丝,我都不知道 gitbook 还有这方面的配置?!

    但是,善良的我总是有求必应,不忍心拒绝小白用户,于是我便抱着试一试的心态开始研究一下如何默认折叠?

    gitbook-issue-modify-default-fold-preview.png

    当然,解决问题前还是要先复现一下问题,然后在命令行中熟练敲入了 gitbook serve 命令来启动本地服务器,为了排除缓存等影响,特意打开了 Chrome 浏览器的无痕模式,果不其然默认左侧菜单是展开的!

    gitbook-issue-modify-default-fold-review.png

    「雪之梦技术驿站」: 不能复现的问题都不是我的问题,拒绝解决此类问题,搞不好是你自己环境搭建问题呢!

    蓦然回首官方文档已走

    问题复现后就要开始寻求解决之道,虽然印象中并没有相关配置,但是难保记忆混乱遗漏了某些配置项,所以还是先看看官方文档怎么说的吧!

    但是,当你在浏览器中输入 gitbook 官方文档 时,并找不到想象中的官方文档而是新版官网,不信你自己去搜一下,肯定是新版官网.

    gitbook-issue-modify-default-fold-document-search-result-preview.png

    当你自以为找到了官网时,点击进去查看文档部分,很遗憾,这是新版文档并不是老版文档,你还会继续百度一下寻求可用链接期待找到官方文档.

    gitbook-issue-modify-default-fold-document-search-result-click.png

    为了节省宝贵时间,这里推荐访问个人维护的 gitbook 文档,点击访问: https://snowdreams1006.github.io/gitbook-official/

    目前提供了中英文两个语言版本的文档,相信可以满足大多数用户的需求了,选择任意一种语言后点击进入翻阅相关设置.

    gitbook-issue-modify-default-fold-gitbook-official-preview.png

    实际上,官方文档也并没有什么用,因为根本就没有提到过如何更改相关配置使其默认折叠而非展开状态.

    gitbook-issue-modify-default-fold-gitbook-official-useless.png

    「雪之梦技术驿站」: 官方不再维护旧版文档,费尽心机找到旧版文档也无济于事,因为并没有提及到相关配置,所以猜测很可能并未提供有关配置项!

    百度一下你就知道了吗

    俗话说:“互联网上绝大多数问题别人都已经遇到过并提供了解决方案,我们唯一要做的就是找到它!”

    这也是面向搜索编程的核心思想,遇到默认折叠问题应该也不会例外,那就搜索一下吧!

    gitbook-issue-modify-default-fold-search-baidu-no-result.png

    虽然百度搜索出现了一些相关文章,但是却不是我们想要的效果,大多数是基于 gitbook 插件实现的目录折叠效果,并不是默认折叠左侧菜单效果.

    不管是换关键词重新搜索还是谷歌搜索,均未发现有关默认折叠左侧菜单的解决方案,难不成面向搜索失败了,要做解决问题的第一人吗?!

    gitbook-issue-modify-default-fold-search-google-no-result.png

    「雪之梦技术驿站」: 多次重复搜索操作均为找到解决方案,由此可见真的很少有人想要默认折叠左侧菜单,我也是很佩服提出该问题的小伙伴骨骼惊奇啊!

    自力更生找寻蛛丝马迹

    既然依靠别人无法解决问题,那么只能自力更生独自解决问题,是时候考验真正的技术了!

    为了排除无关干扰,不能再用自己的 gitbook 项目了,毕竟文件太多不方便后续调试,那么不妨重新创建一个测试项目.

    • 创建测试项目
    $ mkdir test && cd test
    
    • 初始化测试项目
    $ gitbook init
    
    • 启动测试项目
    $ gitbook serve
    

    虽然一片空白,并没有什么实质性内容,但是大道至简,对于我们复现并测试问题来说,足够了!

    gitbook-issue-modify-default-fold-test-serve.png

    打开 Chrome 浏览器并按下 F12 开启调试模式,鼠标选中左侧的 Elements 元素选项卡并点亮左侧的小鼠标,然后在页面上找到左侧图标按钮,于是选中元素高亮了.

    gitbook-issue-modify-default-fold-test-serve-selected-elements.png

    单独摘录 Html 关键代码如下:

    <a class="btn pull-left js-toolbar-action" aria-label="" href="#"><i class="fa fa-align-justify"></i></a>
    

    稍微熟悉前端的小伙伴可能很轻松就能明白 a 标签的 class 属性表示的含义,见名知意,可以这么解释:

    • btn 应该是控制外观的样式,表现得像是按钮效果.
    • pull-left 应该是控制元素的位置,拉倒左边.
    • js-toolbar-action 应该是控制元素的行为,js 工具栏行为动作.

    由此可见,点击该图标实现左侧菜单折叠/展开效果应该是 .js-toolbar-action 在起作用,也就是说某一段 js 肯定是针对该 class 进行了监听!

    此时,点击右侧的 Event Listeners 选项卡查看该元素已监听的 click 事件,定位到是哪一个具体的 js 文件在起作用.

    gitbook-issue-modify-default-fold-test-serve-inspection-listeners.png

    果不其然,元素上存在 click 点击事件监听并且发现执行监听的逻辑代码出现在 theme.js 文件,点击进入文件查看具体内容.

    gitbook-issue-modify-default-fold-test-serve-themejs-ugly.png

    压缩后的 js 代码不具备可读性,点击左下方的 {} 图标可以进行代码格式化,但是可能不是单纯的压缩而是进行了丑化或者混淆代码之类的逻辑,格式化后的代码仍然不可读!

    gitbook-issue-modify-default-fold-test-serve-themejs-format.png

    「雪之梦技术驿站」: 终于发现了蛛丝马迹,修改的代码逻辑就隐藏在 theme.js 文件中,只要找到相关源码重新编译输出 theme.js 文件并替换应该就能实现默认折叠效果!

    不要担心黎明前的黑暗

    根据目前已掌握的线索,可以肯定的是有用线索主要有两个:

    • 监听元素 .js-toolbar-action
    • 输出文件 theme.js

    一个是源码文件,另一个是输出文件,想要在庞大的 gitbook 项目中迅速定位到相关代码逻辑,个人能力有限,并不熟悉前端开发调试流程,因此采用最简单粗暴傻瓜式搜索方式进行排查!

    「雪之梦技术驿站」: 如果读者对于现代前端开发流程比较属性的话,大概过一遍项目结构应该就可以调试定位问题了,用不着像我这样傻瓜式搜索排查!

    • 查看当前 gitbook 版本
    $ gitbook current
    GitBook version is 3.2.3
    
    • 找到 gitbook 安装位置

    gitbook 一般安装在 ~/.gitbook/versions/3.2.3 目录,其中 ~ 表示用户家目录.

    $ open ~/.gitbook/versions/3.2.3
    

    选择一款熟悉的编辑器并打开 Gitbook 安装目录,这里以 sublime 编辑器为例,选中项目后右键全局搜索关键字 js-toolbar-action 期望找到相关源码文件.

    gitbook-issue-modify-default-fold-source-sublime-search.png

    全局搜索后主要出现两个文件包含 js-toolbar-action 关键字,一个是输出文件 theme.js ,另一个是源码文件 toolbar.js .

    Searching 19744 files for "js-toolbar-action"
    
    /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/_assets/website/theme.js:
    
    ...
    
    /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/js/theme/toolbar.js:
    
    ...
    
    4 matches across 2 files
    

    可想而知,源码文件肯定是经过编译处理后统一打包输出,因此不仅仅要找到源码文件还要掌握如何编译.

    「雪之梦技术驿站」: 定位到当前 gitbook 目录后借助全局搜索功能定位到具体的文件路径,起作用的是 gitbook-plugin-theme-default 项目,其实这就是 Gitbook 的默认主题.

    源码在哪

    /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/js/theme/toolbar.js :

    // Update a button
    function updateButton(opts) {
        var $result;
        var $toolbar = $('.book-header');
        var $title = $toolbar.find('h1');
    
        // Build class name
        var positionClass = 'pull-' opts.position;
    
        // Create button
        var $btn = $('<a>', {
            'class': 'btn',
            'text': opts.text? ' '   opts.text : '',
            'aria-label': opts.label,
            'href': '#'
        });
    
        // Bind click
        $btn.click(opts.onClick);
    
        // Prepend icon
        if (opts.icon) {
            $('<i>', {
                'class': opts.icon
            }).prependTo($btn);
        }
    
        // Prepare dropdown
        if (opts.dropdown) {
            var $container = $('<div>', {
                'class': 'dropdown ' positionClass ' ' opts.className
            });
    
            // Add button to container
            $btn.addClass('toggle-dropdown');
            $container.append($btn);
    
            // Create inner menu
            var $menu = createDropdownMenu(opts.dropdown);
    
            // Menu position
            $menu.addClass('dropdown-' (opts.position == 'right'? 'left' : 'right'));
    
            $container.append($menu);
            $result = $container;
        } else {
            $btn.addClass(positionClass);
            $btn.addClass(opts.className);
            $result = $btn;
        }
    
        $result.addClass('js-toolbar-action');
    
        if ($.isNumeric(opts.index) && opts.index >= 0) {
            insertAt($toolbar, '.btn, .dropdown, h1', opts.index, $result);
        } else {
            $result.insertBefore($title);
        }
    }
    
    // Update all buttons
    function updateAllButtons() {
        $('.js-toolbar-action').remove();
        buttons.forEach(updateButton);
    }
    

    粗略看一下,上述代码是实现触发左侧图标折叠/展开菜单的逻辑实现,这里只是具体实现还不知道谁是使用者,也就是说这种逻辑是在哪里调用的?

    只能继续顺藤摸瓜,往上翻看,根据基本开发常识,在该文件的同级目录中存在如下文件,其中的 index.js 应该就是入口文件:

    snowdreams1006s-MacBook-Pro:theme snowdreams1006$ tree .
    .
    ├── dropdown.js
    ├── index.js
    ├── keyboard.js
    ├── loading.js
    ├── navigation.js
    ├── platform.js
    ├── sidebar.js
    └── toolbar.js
    
    0 directories, 8 files
    snowdreams1006s-MacBook-Pro:theme snowdreams1006$ 
    

    打开 index.js 文件,根据注释我们可以看到 init() 函数是入门函数,其中 sidebar.init()sidebar.toggle() 函数无不说明 sidebar.jstoolbar.js 关系密切,完全有理由猜想 sidebar.jstoolbar.js 的使用者!

    function init() {
        // Init sidebar
        sidebar.init();
    
        // Init keyboard
        keyboard.init();
    
        // Bind dropdown
        dropdown.init();
    
        // Init navigation
        navigation.init();
    
        // Add action to toggle sidebar
        toolbar.createButton({
            index: 0,
            icon: 'fa fa-align-justify',
            onClick: function(e) {
                e.preventDefault();
                sidebar.toggle();
            }
        });
    }
    

    打开 sidebar.js 文件并查看 init() 初始化函数和 toggle() 触发函数,可以验证我们的猜想,这里就是控制中心!

    // Prepare sidebar: state and toggle button
    function init() {
        // Init last state if not mobile
        if (!platform.isMobile()) {
            toggleSidebar(gitbook.storage.get('sidebar', true), false);
        }
    
        // Close sidebar after clicking a link on mobile
        $(document).on('click', '.book-summary li.chapter a', function(e) {
            if (platform.isMobile()) toggleSidebar(false, false);
        });
    }
    

    「雪之梦技术驿站」: 非手机端初始化上次状态,默认展开侧边栏,如果是手机端则折叠侧边栏.其中 toggleSidebar() 接收两个参数,第一次参数表示是展开还是折叠,第二个参数暂不可知.

    // Toggle sidebar with or withour animation
    function toggleSidebar(_state, animation) {
        if (gitbook.state != null && isOpen() == _state) return;
        if (animation == null) animation = true;
    
        gitbook.state.$book.toggleClass('without-animation', !animation);
        gitbook.state.$book.toggleClass('with-summary', _state);
    
        gitbook.storage.set('sidebar', isOpen());
    }
    

    「雪之梦技术驿站」: 第一个参数确实表示状态而第二个参数表示是否有动画效果,不用看具体代码逻辑而是看注释就能猜出大概逻辑了.

    通过上述分析,我们可以得知 init() 初始化函数决定了默认行为是折叠还是展开,同时 gitbook.storage.set('sidebar', isOpen())gitbook.storage.get('sidebar', true) 应该是设置和获取是否展开菜单的标志!

    由此,如果想要默认折叠左侧菜单,那么只需要设置成 gitbook.storage.set('sidebar', false) 应该就会生效!

    如何编译

    说干就干,于是乎在 init() 函数插入 gitbook.storage.set('sidebar', false) 默认折叠逻辑,接着看一下是否需要重新编译才能生效?

    // Prepare sidebar: state and toggle button
    function init() {
        // Close sidebar as default state 
        gitbook.storage.set('sidebar', false);
    
        // Init last state if not mobile
        if (!platform.isMobile()) {
            toggleSidebar(gitbook.storage.get('sidebar', true), false);
        }
    
        // Close sidebar after clicking a link on mobile
        $(document).on('click', '.book-summary li.chapter a', function(e) {
            if (platform.isMobile()) toggleSidebar(false, false);
        });
    }
    

    接着切换到测试项目再次运行 gitbook serve 启动本地服务器,发现并没有任何变化,很有可能改变源码文件需要重新编译才会生效或者说更改的源码项目也没有生效?

    gitbook-issue-modify-default-fold-test-serve-again-fail.png

    「雪之梦技术驿站」: 该源码文件所在的项目是 gitbook-plugin-theme-default ,根据 gitbook 插件命名规范我们知道,gitbook-plugin-* 一般是功能性插件,这一类的插件有 gitbook-plugin-readmore 阅读更多插件和 gitbook-plugin-copyright 版权保护插件等等.

    但是如果插件名以 gitbook-plugin-theme 开头的话,这一类插件就是主题插件,比如 gitbook-plugin-theme-default 就是默认主题.

    除此之外,只要遵守该命名规则的插件引入时无需添加 gitbook-plugin- 前缀,可以直接在 gitbook.json 文件中引入剩余的简称作为插件名.

    摘录自 Gitbook 项目的配置文件,可以佐证上述规则的正确性.

    "plugins": [
        "toc",
        "pageview-count",
        "mermaid-gb3",
        "-lunr",
        "-search",
        "search-plus",
        "splitter",
        "-sharing",
        "sharing-plus",
        "expandable-chapters-small",
        "anchor-navigation-ex",
        "edit-link",
        "copy-code-button",
        "chart",
        "favicon-custom",
        "github-buttons",
        "advanced-emoji",
        "rss",
        "readmore",
        "copyright",
        "tbfed-pagefooter",
        "mygitalk",
        "donate"
    ]
    

    作为普通的 nodejs 包,开发规范规定了 package.json 提供了插件的配置信息,而 Gitbook 插件除了是标准的 nodejs 包之外还有自己的约束,主要体现在提供了 gitbook 节点属性:

    "gitbook": {
        "properties": {
          "styles": {
            "type": "object",
            "title": "Custom Stylesheets",
            "properties": {
              "website": {
                "title": "Stylesheet for website output",
                "default": "styles/website.css"
              },
              "pdf": {
                "title": "Stylesheet for PDF output",
                "default": "styles/pdf.css"
              },
              "epub": {
                "title": "Stylesheet for ePub output",
                "default": "styles/epub.css"
              },
              "mobi": {
                "title": "Stylesheet for Mobi output",
                "default": "styles/mobi.css"
              },
              "ebook": {
                "title": "Stylesheet for ebook outputs (PDF, ePub, Mobi)",
                "default": "styles/ebook.css"
              },
              "print": {
                "title": "Stylesheet to replace default ebook css",
                "default": "styles/print.css"
              }
            }
          },
          "showLevel": {
            "type": "boolean",
            "title": "Show level indicator in TOC",
            "default": false
          }
        }
    }
    

    默认主题仅仅提供了两个配置项,分别是 styles 样式文件位置和 showLevel 是否显示层级配置.

    再一次验证了猜想的正确性,真的需要修改源码才能实现默认折叠左侧菜单的效果,紧着继续在 package.json 中找到项目源码的托管地址,看一下有没有提供二次开发文档.

    "repository": {
        "type": "git",
        "url": "git https://github.com/GitbookIO/theme-default.git"
    }
    

    令人遗憾的是,项目介绍空空如也,除了一张主题预览图,别的什么都没有?!

    gitbook-issue-modify-default-fold-theme-default-github-preview.png

    既然没有二次开发文档,那就看看项目源码有没有别的蛛丝马迹教我们如何编译?

    「雪之梦技术驿站」: 绕了这么多,其实还不是因为比较菜,人家都提供给源码都不会编译,留下来没有技术的眼泪!

    视角再一次切换到源码目录,除了 jsless 目录外,竟然还有一个 build.sh 构建脚本!

    snowdreams1006s-MacBook-Pro:src snowdreams1006$ tree 
    .
    ├── build.sh
    ├── js
    │   ├── core
    │   └── theme
    │       ├── dropdown.js
    │       ├── index.js
    │       ├── keyboard.js
    │       ├── loading.js
    │       ├── navigation.js
    │       ├── platform.js
    │       ├── sidebar.js
    │       └── toolbar.js
    └── less
    
    7 directories, 37 files
    snowdreams1006s-MacBook-Pro:src snowdreams1006$ 
    

    这一刻,仿佛看到了九点钟升起的太阳,未来是你们的也是我们的!

    snowdreams1006s-MacBook-Pro:gitbook-plugin-theme-default snowdreams1006$ cat src/build.sh 
    #! /bin/bash
    
    # Cleanup folder
    rm -rf _assets
    
    # Recreate folder
    mkdir -p _assets/website/
    mkdir -p _assets/ebook/
    
    # Compile JS
    browserify src/js/core/index.js | uglifyjs -mc > _assets/website/gitbook.js
    browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js
    
    # Compile Website CSS
    lessc -clean-css src/less/website.less _assets/website/style.css
    
    # Compile eBook CSS
    lessc -clean-css src/less/ebook.less _assets/ebook/ebook.css
    lessc -clean-css src/less/pdf.less _assets/ebook/pdf.css
    lessc -clean-css src/less/mobi.less _assets/ebook/mobi.css
    lessc -clean-css src/less/epub.less _assets/ebook/epub.css
    
    # Copy fonts
    mkdir -p _assets/website/fonts
    cp -R node_modules/font-awesome/fonts/ _assets/website/fonts/fontawesome/
    
    # Copy icons
    mkdir -p _assets/website/images
    cp node_modules/gitbook-logos/output/favicon.ico _assets/website/images/
    cp node_modules/gitbook-logos/output/apple-touch-icon-152.png _assets/website/images/apple-touch-icon-precomposed-152.png
    
    snowdreams1006s-MacBook-Pro:gitbook-plugin-theme-default snowdreams1006$ 
    

    这一段脚本中除了看不懂 browserify,uglifyjs,lessc -clean-css 命令外,剩下部分都很简单,大致是编译源码文件并输出到 _assets 目录.

    编译 js 的命令主要有以下两条,而我们关心的 theme.js 仅涉及到一条,除此之外没有任何别的依赖,这一点非常好!

    # Compile JS
    browserify src/js/core/index.js | uglifyjs -mc > _assets/website/gitbook.js
    browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js
    

    接下来的重点就是如何运行 browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js 命令了!

    摇身一变重新编译源码

    browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js

    百度一下 browserify

    再一次打开熟悉的浏览器输入关键字 browserify 后出现一系列相关文章,很好奇为啥排名第一个都不会是官网呢?不管怎么样,找到 browserifygithub 项目地址也是不错的!

    gitbook-issue-modify-default-fold-search-browserify.png

    这里并不关心 browserify 到底是什么,只在乎如何安装基本环境而已!

    $ npm install -g browserify
    

    「雪之梦技术驿站」: 如果是 mac 电脑,全局安装需要管理员权限,应该运行 sudo npm install -g browserify ,如果嫌弃安装速度慢也可以运行 cnpm install -g browserify ,前提是已安装 cnpm 命令.

    谷歌一下 uglifyjs

    不吹不黑,少走一点弯路,直接就找到了 github 项目网址,同样的也不关心项目介绍,直接翻看如何安装部分.

    $ npm install -g uglify-js
    

    gitbook-issue-modify-default-fold-search-uglifyjs.png

    重新编译 others

    涉及到 browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js 命令的两个插件均已安装完毕,理所应当开始重新编译源码了,但是竟然报错了?

    当出现报错时,开始怀疑人生,难道推论不正确,难道环境没有安装成功吗,为啥提示找不到 mousetrap 模块?

    $ browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js
    Error: Cannot find module 'mousetrap' from '/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/js/theme'
        at /usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:46:17
        at process (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:173:43)
        at ondir (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:188:17)
        at load (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:69:43)
        at onex (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:92:31)
        at /usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:22:47
        at FSReqCallback.oncomplete (fs.js:158:21)
    

    算了吧,与其费尽心思猜测为啥无法加载 mousetrap 模块,不如继续安装剩余依赖,最大可能性排除环境问题.

    那就先把 src/build.sh 构建脚本涉及到的其他命令全部安装一遍,然后再试一下吧!

    除了编译 Js 的命令外,还有编译 Css 的命令,关于构建脚本 build.sh 的其他内容就是基本的复制粘贴之类的操作了.

    # Compile Website CSS
    lessc -clean-css src/less/website.less _assets/website/style.css
    

    这里省略面向搜索编程的中间过程,安装命令如下:

    $ npm install -g less less-plugin-clean-css
    

    当我再一次运行构建脚本时,满心期待会编译成功,没想到现实再一次打脸,这时候错误更多了呢,真的是没想到!

    snowdreams1006s-MacBook-Pro:gitbook-plugin-theme-default snowdreams1006$ src/build.sh 
    Error: Cannot find module 'jquery' from '/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/js/core'
        at /usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:46:17
        at process (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:173:43)
        at ondir (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:188:17)
        at load (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:69:43)
        at onex (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:92:31)
        at /usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:22:47
        at FSReqCallback.oncomplete (fs.js:158:21)
    Error: Cannot find module 'mousetrap' from '/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/js/theme'
        at /usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:46:17
        at process (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:173:43)
        at ondir (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:188:17)
        at load (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:69:43)
        at onex (/usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:92:31)
        at /usr/local/lib/node_modules/browserify/node_modules/_resolve@1.1.7@resolve/lib/async.js:22:47
        at FSReqCallback.oncomplete (fs.js:158:21)
    FileError: '../../node_modules/font-awesome/less/font-awesome.less' wasn't found. Tried - /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/node_modules/font-awesome/less/font-awesome.less,/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/node_modules/font-awesome/less/font-awesome.less,../../node_modules/font-awesome/less/font-awesome.less in /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/less/website.less on line 2, column 1:
    1 @import "base/all.less";
    2 @import "../../node_modules/font-awesome/less/font-awesome.less";
    3 @import "../../node_modules/preboot/less/preboot.less";
    
    FileError: '../../../node_modules/gitbook-markdown-css/less/mixin.less' wasn't found. Tried - /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/node_modules/gitbook-markdown-css/less/mixin.less,/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/node_modules/gitbook-markdown-css/less/mixin.less,../../../node_modules/gitbook-markdown-css/less/mixin.less in /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/less/base/mixins.less on line 1, column 1:
    1 @import "../../../node_modules/gitbook-markdown-css/less/mixin.less";
    2 
    
    FileError: '../../../node_modules/gitbook-markdown-css/less/mixin.less' wasn't found. Tried - /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/node_modules/gitbook-markdown-css/less/mixin.less,/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/node_modules/gitbook-markdown-css/less/mixin.less,../../../node_modules/gitbook-markdown-css/less/mixin.less in /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/less/base/mixins.less on line 1, column 1:
    1 @import "../../../node_modules/gitbook-markdown-css/less/mixin.less";
    2 
    
    FileError: '../../../node_modules/gitbook-markdown-css/less/mixin.less' wasn't found. Tried - /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/node_modules/gitbook-markdown-css/less/mixin.less,/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/node_modules/gitbook-markdown-css/less/mixin.less,../../../node_modules/gitbook-markdown-css/less/mixin.less in /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/less/base/mixins.less on line 1, column 1:
    1 @import "../../../node_modules/gitbook-markdown-css/less/mixin.less";
    2 
    
    FileError: '../../../node_modules/gitbook-markdown-css/less/mixin.less' wasn't found. Tried - /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/node_modules/gitbook-markdown-css/less/mixin.less,/Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/node_modules/gitbook-markdown-css/less/mixin.less,../../../node_modules/gitbook-markdown-css/less/mixin.less in /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/less/base/mixins.less on line 1, column 1:
    1 @import "../../../node_modules/gitbook-markdown-css/less/mixin.less";
    2 
    
    cp: directory _assets/website/fonts/fontawesome does not exist
    cp: node_modules/gitbook-logos/output/favicon.ico: No such file or directory
    cp: node_modules/gitbook-logos/output/apple-touch-icon-152.png: No such file or directory
    

    那就继续扩大安装环境范围,这时候对整个 gitbook-plugin-theme-default 进行 npm install 安装相关依赖,这一次会发生什么情况呢?

    $ npm install
    

    让我们拭目以待!

    snowdreams1006s-MacBook-Pro:gitbook-plugin-theme-default snowdreams1006$ src/build.sh 
    snowdreams1006s-MacBook-Pro:gitbook-plugin-theme-default snowdreams1006$
    

    命令行没有了乱七八糟的输出,世界变得安静了!

    linux 命令行哲学告诉我们,没有消息就是好消息,全部安装项目环境后再次运行 src/build.sh 脚本命令行瞬间安静了!

    怀着忐忑不安的心,切换到测试项目运行 gitbook serve 命令后,那一瞬间,感觉世界都静止了,奇迹就这么发生了?

    gitbook-issue-modify-default-fold-test-serve-again-success.png

    终于成功了,实现默认折叠效果了吗?

    为了验证是否成功实现默认折叠失效,做一次反向测试,既然默认折叠左侧菜单设置的是 false,如果设置成 true 的话,默认应该是展开状态.

    // Prepare sidebar: state and toggle button
    function init() {
        // Close sidebar as default state 
        // gitbook.storage.set('sidebar', false);
    
        // Open sidebar as default state 
        gitbook.storage.set('sidebar', true);
    
        // Init last state if not mobile
        if (!platform.isMobile()) {
            toggleSidebar(gitbook.storage.get('sidebar', true), false);
        }
    
        // Close sidebar after clicking a link on mobile
        $(document).on('click', '.book-summary li.chapter a', function(e) {
            if (platform.isMobile()) toggleSidebar(false, false);
        });
    }
    

    重新编译后再次启动本地测试项目,如果是展开状态,那就说明成功不是偶然而是靠技巧和努力!

    • 重新编译源码
    $ src/build.sh
    

    /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default

    • 启动本地项目
    $ gitbook serve
    

    /Users/snowdreams1006/Documents/workspace/test

    gitbook-issue-modify-default-fold-test-serve-again-verify.png

    「雪之梦技术驿站」: 苦心人天不负,不是昙花一现的巧合而是货真价实的现实,就这么实现了默认折叠左侧菜单功能!

    懒人直达以及回顾总结

    如果你是 Gitbook 普通用户或者懒得折腾,那么推荐你直接替换掉 theme.js 文件:

    • 查看正在使用的 gitbook 版本信息
    $ gitbook current
    GitBook version is 3.2.3
    
    • 打开正在使用的 gitbook 安装位置
    $ open ~/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/
    
    • 新文件替换掉原来的 _assets/website/theme.js 文件

    可以关注微信公众号回复 “gitbook” 获取重新编译后的新文件 theme.js.

    • 切换到测试项目验证默认折叠是否已生效
    $ gitbook serve
    

    如果你不怕麻烦,喜欢折腾,那么不妨体验一下如何重新编译源码文件.

    • 查看正在使用的 gitbook 版本信息
    $ gitbook current
    GitBook version is 3.2.3
    
    • 打开正在使用的 gitbook 安装位置
    $ open ~/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/
    
    • 安装 theme-default 默认主题项目所需依赖
    $ npm install
    
    • 安装 build.sh 构建脚本所需依赖
    $ sudo npm install -g browserify uglify-js less less-plugin-clean-css
    
    • 运行 build.sh 构建脚本重新编译
    $ src/build.sh
    
    • 切换到测试项目验证默认折叠是否已生效
    $ gitbook serve
    

    值得注意的是,实现默认折叠左侧菜单功能仅仅需要添加一行代码,但是也很有可能和项目中已引入插件存在冲突,毕竟 sidebar 的状态也可以被未知代码所更改!

    // Prepare sidebar: state and toggle button
    function init() {
        // Close sidebar as default state 
        gitbook.storage.set('sidebar', false);
    
        // Open sidebar as default state 
        // gitbook.storage.set('sidebar', true);
    
        // Init last state if not mobile
        if (!platform.isMobile()) {
            toggleSidebar(gitbook.storage.get('sidebar', true), false);
        }
    
        // Close sidebar after clicking a link on mobile
        $(document).on('click', '.book-summary li.chapter a', function(e) {
            if (platform.isMobile()) toggleSidebar(false, false);
        });
    }
    

    最后希望本文对你有所帮助,面向搜索编程变得不可用时,自力更生也未尝不可,如果大家在使用 Gitbook 中遇到任何问题,欢迎留言评论告诉我,当然我也不一定保证解决,万一哪天心血来潮翻看一下源码就解决了呢!

    如果你觉得本文对你有所帮助,请随手点个赞再走呗或者关注下公众号「雪之梦技术驿站」定期更新优质文章哟!

    雪之梦技术驿站.png

    展开全文
  • ubuntu14.04安装gitbook和使用

    千次阅读 2016-10-28 20:52:41
    gitbook 是基于nodejs的一个命令行工具,可使用 Github/Git 和 Markdown 来制作精美的电子书,可以协同开发(主要是利用github)。具体gitbook是什么自行搜索,其实没必要搞懂,会用gitbook ,git命令,这个弄熟练后 ...
  • 如果你平时工作比较忙,但是还想专注于基础的话,建议看看这一篇,会带你有全新的认识。
  • 安装了GitBook,内网使用,没法用上gitbook的网页。 用gitbook serve只能展示一本书,而且也不利于长期维护。 于是使用gitlab,jenkins,和nginx配合gitbook使用。 基本的流程是这样的,每本书作为项目托管到gitlab...
  • OpenStack 快速进阶教程

    千次阅读 2018-04-12 10:41:44
    强调通过集成和测试的速度,快速出一个集成的结果(是失败还是成功),在代码集成之前,必须先通过自动化测试验证,只要有一个测试用例失败,就不能集成。 Martin Fowler 说过,“持续集成并不能消除Bug,而是让...
  • SQLMap 从入门到入狱详细指南

    千次阅读 2018-11-06 11:51:56
    SQLMap 是一个开源的渗透测试工具,可以用来进行自动化检测,利用 SQL 注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,...
  • 接口提供方的接口方法可能还需要其他地方使用,但是又加上了一些接口验证的参数。老手当然业务代码抽出来作为新的方法同时接口和其他地方使用。此时一位萌新使用了 ctrl+c 和 ctrl+v,并膜拜了下大神的代码。接口...
  • Angular 基础教程(7.0)

    千次阅读 2018-11-26 13:17:42
    一些开发者来抱怨说 @angular/cli 在打包的时候加上 --prod 参数会报错,无法编译。这是一个很常见的问题,因为 @angular/cli 最新的版本经常会有 bug,只要在项目的 package.json 里面降低一个小版本号就 OK 了。...
  • Notes Twentieth Day-渗透攻击-红队-权限提升(dayu) ** 作者:大余 时间:2020-10-5 请注意:对于所有笔记中复现的这些终端或者服务器,都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器...
  • Python 全栈 60 天精通之路

    千次阅读 2020-02-11 23:30:03
    图文并茂,加上有趣的例子、有趣的小项目,学起来更有乐趣。 第三,自成体系。 就像侦探片那样,一步一步,一环扣一环地铺开 Python 技术栈。 第四,剖析一些 Python 常见的面试题。 将理论知识讲解,结合案例,...
  • 打比方说你要去亚马逊上买书,之前你只能通过购物网站购买后从美国发货过海关等重重关卡送到你的家里,现在在中国建立一个亚马逊分基地,你就不用通过美国进行邮寄,从中国就能把书尽快你送到。 WAF WAF 是一种 ...
  • 创建和破坏容器的开销较低,再加上单个虚拟机中的高包装密度,使容器成为部署各个微服务的完美计算工具。 Google 主导成立了云原生计算基金会(CNCF),对云原生的定义为: “云原生(Cloud Native)技技术帮助企业...
  • - group 加上之前的 domian 即此 CRD 的 Group: apps.kruise.io; - version 一般分三种,按社区标准: - v1alpha1: 此 api 不稳定,CRD 可能废弃、字段可能随时调整,不要依赖; - v1beta1: api 已稳定,会保证向...
  • 零基础入门微信小程序开发 (2020 版)

    万次阅读 多人点赞 2020-02-19 23:30:02
    另外加上开发工具的安装、小程序发布等内容,共 9 篇文章。 本专栏共包含四个部分。 第一部分(1-3)带你初步了解小程序是什么,然后进行小程序开发的准备工作,从注册账号到安装开发工具一应俱全。工欲善其事,必先...
  • Jenkins集成Gitlab配置提交流水线

    千次阅读 2020-02-11 23:30:50
    邮件通知的功能很重要,我们要为每条流水线都加上这个步骤,我们在共享库中封装一个 toemail.groovy 。 新建文件 src/org/devops/toemail.groovy 。在这个文件中,我们写了一段 HTML 代码,主要展示 Jenkins 的构建...
  • 在单体环境下,我们可以很轻松的使用切面进行权限验证,而在微服务的场景中,服务之间相互调用是难以控制的。 拆分服务或者服务边界划分是另一件很难做到的事情,最吃香的理论也许是根据 DDD 去进行划分,天然的领域...
  • 程序员的 MySQL 面试金典

    千次阅读 2019-09-25 23:30:02
    MySQL 操作命令和内置函数,MySQL 的操作命令,对于程序员或者 DBA 来说也是必须具备的一项技能,比如,用户和权限的创建、数据库相关信息的查询等,都离不开对 MySQL 命令行的掌握。对内置函数的掌握程度,代表了...
  • 前端工程化工具

    2019-09-10 23:30:29
    注:加上--unsafe-pern 的原因是防止包 grywarn 权限错误 修改配置文件 config.yaml,在最后添加监听的端口,端口可修改 listen:0.0.0.0:4873 注:如果不知道 config.yaml 的路径,可以先直接启动 verdaccio,启动日志...
  • 自然语言处理面试基础

    千次阅读 2020-01-01 23:30:03
    付费用户可享受文章永久阅读权限。 本专栏为虚拟产品,一经付费概不退款,敬请谅解。 本专栏可在 GitChat 服务号、App 及网页端 gitbook.cn 上购买,一端购买,多端阅读。 订阅福利 本专栏限时特价 39 元,2020 年...
  • Web 安全恩仇录:漏洞原理

    千次阅读 2018-04-12 10:41:44
    渗透测试评估系统的安全须是长期性的、定时的测试,原因在于现在很多的企业业务线拉的非常长,加上还有外包的因素,导致开发人员水平不齐,造成漏洞的出现。 渗透测试的流程? 渗透测试人员在实施渗透测试的过程中多...
  • 盗取各类用户帐号权限(控制所盗窃权限数据内容),如机器登录帐号、用户网银帐号、各类管理员帐号 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力 基于XSS的跨站业务请求(如:非法转账、非法下单、...
  • 从 0 开始搭建 IoT 平台

    千次阅读 2019-07-29 23:30:03
    ,对设备的创建、接入、 上线/下线、 禁用/恢复和删除的整个生命周期进行管理,引入设备的发布订阅权限管理。同时也会 把服务端代码和设备端代码的框架搭建起来 ,便于后续的迭代开发。这部分最后也会讲解 如何横向...
  • 如果你初入职场,你是否对职场充满好奇与期待;如果你刚刚跳槽,你是否迫切地希望展示自己的才华!...2、初入公司如何自己设定目标; 3、作为程序员,如何快速上手项目; 4、作为新人,如何快速了解公...
  • 就是权限认证,也就是常说的权限系统。由于鉴权服务有非常高的相似性,就可以进行抽象处理,放在网关层。 比如 https 协议的统一接入,分布式 session 的处理问题,新的登录鉴权通道的接入等。 2.3 流量控制 流量...
  • 为例,首先我们可以通过以下命令查看该索引文件的内容,可以看到输出结构为,position>,实际上索引文件中保存的并不是offset而是相对位移,比如第一条消息的相对位移则为0,格式化输出时加上了基准偏移量。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 657
精华内容 262
关键字:

如何给gitbook加上权限