Ghost 开源博客平台

Ghost 是一个简洁、强大的写作平台。你只须专注于用文字表达你的想法就好,其余的事情就让 Ghost 来帮你处理吧。

深度玩转 Ghost 0.4.2 之:删除默认导入的数据

无论你是第一次还是第 N 次安装 Ghost,每次安装完之后,都能看到一篇熟悉的文章:

是否看腻了?是否每次安装之后都要登陆后台手工删掉它?如果你不想再看到它,希望安装个干净的 Ghost ,那就跟我来吧!

关键文件

Ghost 安装流程中包含了一个导入初始化数据的过程,这些初始化数据就存放在 core/server/data/fixtures/index.js 文件中。OK,既然知道源头了,我们就来动手修改吧!

打开 core/server/data/fixtures/index.js 文件,内容如下:

var sequence   = require('when/sequence'),  
    _          = require('lodash'),
    Post       = require('../../models/post').Post,
    Tag        = require('../../models/tag').Tag,
    Role       = require('../../models/role').Role,
    Permission = require('../../models/permission').Permission;

var fixtures = {  
    posts: [
        {
            "title":            "Welcome to Ghost",
            "slug":             "welcome-to-ghost",
            "markdown":         "You're live! Nice. We've put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at `<your blog URL>/ghost/`. When you arrive, you can select this post from a list on the left and see a preview of it on the right. Click the little pencil icon at the top of the preview to edit this post and read the next section!\n\n## Getting Started\n\nGhost uses something called Markdown for writing. Essentially, it's a shorthand way to manage your post formatting as you write!\n\nWriting in Markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use *shortcuts* to **style** your content. For example, a list:\n\n* Item number one\n* Item number two\n    * A nested item\n* A final item\n\nor with numbers!\n\n1. Remember to buy some milk\n2. Drink the milk\n3. Tweet that I remembered to buy the milk, and drank it\n\n### Links\n\nWant to link to a source? No problem. If you paste in url, like http://ghost.org - it'll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here's a link to [the Ghost website](http://ghost.org). Neat.\n\n### What about Images?\n\nImages work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:\n\n![The Ghost Logo](https://ghost.org/images/ghost.png)\n\nNot sure which image you want to use yet? That's ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:\n\n![A bowl of bananas]\n\n\n### Quoting\n\nSometimes a link isn't enough, you want to quote someone on what they've said. It was probably very wisdomous. Is wisdomous a word? Find out in a future release when we introduce spellcheck! For now - it's definitely a word.\n\n> Wisdomous - it's definitely a word.\n\n### Working with Code\n\nGot a streak of geek? We've got you covered there, too. You can write inline `<code>` blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.\n\n    .awesome-thing {\n        display: block;\n        width: 100%;\n    }\n\n### Ready for a Break? \n\nThrow 3 or more dashes down on any new line and you've got yourself a fancy new divider. Aw yeah.\n\n---\n\n### Advanced Usage\n\nThere's one fantastic secret about Markdown. If you want, you can  write plain old HTML and it'll still work! Very flexible.\n\n<input type=\"text\" placeholder=\"I'm an input field!\" />\n\nThat should be enough to get you started. Have fun - and let us know what you think :)",
            "image":            null,
            "featured":         false,
            "page":             false,
            "status":           "published",
            "language":         "en_US",
            "meta_title":       null,
            "meta_description": null
        }
    ],

    tags: [
        {
            "name":             "Getting Started",
            "slug":             "getting-started",
            "description":      null,
            "parent_id":        null,
            "meta_title":       null,
            "meta_description": null
        }
    ],

    roles: [
        {
            "name":             "Administrator",
            "description":      "Administrators"
        },
        {
            "name":             "Editor",
            "description":      "Editors"
        },
        {
            "name":             "Author",
            "description":      "Authors"
        }
    ],

    permissions: [
        {
            "name":             "Edit posts",
            "action_type":      "edit",
            "object_type":      "post"
        },
        {
            "name":             "Remove posts",
            "action_type":      "remove",
            "object_type":      "post"
        },
        {
            "name":             "Create posts",
            "action_type":      "create",
            "object_type":      "post"
        }
    ]
};

module.exports = {  
    populateFixtures: function () {
        var ops = [];

        _.each(fixtures.posts, function (post) {
            ops.push(function () {return Post.add(post); });
        });

        _.each(fixtures.tags, function (tag) {
            ops.push(function () {return Tag.add(tag); });
        });

        _.each(fixtures.roles, function (role) {
            ops.push(function () {return Role.add(role); });
        });
        _.each(fixtures.permissions, function (permission) {
            ops.push(function () {return Permission.add(permission); });
        });

        // add the tag to the post
        ops.push(function () {
            Post.forge({id: 1}).fetch({withRelated: ['tags']}).then(function (post) {
                post.tags().attach([1]);
            });
        });

        // finally, grant admins all permissions
        ops.push(function () {
            Role.forge({id: 1}).fetch({withRelated: ['permissions']}).then(function (role) {
                role.permissions().attach([1, 2, 3]);
            });
        });

        return sequence(ops);
    }
};

分析上述代码,需要修改的部分如下:

  1. fixtures 对象包含了两个重要的属性:poststags ,他们就是文章和标签的初始化数据。既然找到源头了,我们只需将这两个属性清空即可。
  2. 下面所列代码的作用是把默认数据中的标签(tag)和文章(post)做关联,这个也需要删除。由于这段代码执行的 SQL 语句中的参数是写死的,如果不删除的话,Ghost 初始化时执行到这里就会报错。
// add the tag to the post
ops.push(function () {  
    Post.forge({id: 1}).fetch({withRelated: ['tags']}).then(function (post) {
        post.tags().attach([1]);
    });
});

对上述两处地方修改之后,最终代码如下:

var sequence   = require('when/sequence'),  
    _          = require('lodash'),
    Post       = require('../../models/post').Post,
    Tag        = require('../../models/tag').Tag,
    Role       = require('../../models/role').Role,
    Permission = require('../../models/permission').Permission;

var fixtures = {  
    posts: [
    ],

    tags: [
    ],

    roles: [
        {
            "name":             "Administrator",
            "description":      "Administrators"
        },
        {
            "name":             "Editor",
            "description":      "Editors"
        },
        {
            "name":             "Author",
            "description":      "Authors"
        }
    ],

    permissions: [
        {
            "name":             "Edit posts",
            "action_type":      "edit",
            "object_type":      "post"
        },
        {
            "name":             "Remove posts",
            "action_type":      "remove",
            "object_type":      "post"
        },
        {
            "name":             "Create posts",
            "action_type":      "create",
            "object_type":      "post"
        }
    ]
};

module.exports = {  
    populateFixtures: function () {
        var ops = [];

        _.each(fixtures.posts, function (post) {
            ops.push(function () {return Post.add(post); });
        });

        _.each(fixtures.tags, function (tag) {
            ops.push(function () {return Tag.add(tag); });
        });

        _.each(fixtures.roles, function (role) {
            ops.push(function () {return Role.add(role); });
        });
        _.each(fixtures.permissions, function (permission) {
            ops.push(function () {return Permission.add(permission); });
        });

        // finally, grant admins all permissions
        ops.push(function () {
            Role.forge({id: 1}).fetch({withRelated: ['permissions']}).then(function (role) {
                role.permissions().attach([1, 2, 3]);
            });
        });

        return sequence(ops);
    }
};

保存文件。至此大功告成!再次安装 Ghost ,是否没有了烦人的默认数据了?

说明

你是否会有疑问,修改 core/server/data/fixtures/index.js 文件会不会影响将来的升级?

非常肯定的告诉你:绝无影响!

我们修改的这个文件仅仅是一些初始化数据,一旦系统和数据库初始化之后,将来升级 Ghost 时,Ghost会检查你所配置的数据库是否已经初始化过、是否数据库版本低,如果需要升级数据库,Ghost 会通过专门的脚本对数据库进行升级,不会产生丝毫的影响。

王赛
关于作者 王赛