hexo icon indicating copy to clipboard operation
hexo copied to clipboard

Defining a custom source path for a custom layout

Open ebsen opened this issue 10 years ago • 4 comments

Hi. Hexo's Layout documentation states that "Custom layouts are saved to the source/_posts folder."

I'm wondering if I can define my own path for a custom layout so that running hexo new project <title> would create a new Markdown file at source/_projects rather than the default, source/_posts.

Perhaps there's a way to do this but I can't make out how.

ebsen avatar Dec 27 '15 21:12 ebsen

This is exactly what I was wondering.

Also, if I might add on to this I would also like to create a file structure inside of my _posts/ folder. For example to create something like this: _posts/year/month/post.md. Otherwise I will end up with hundreds of posts inside of that single directory.

awulkan avatar Jan 10 '16 21:01 awulkan

Anything new here? I want to have subfolders in _posts too.

Edit

new_post_name: :year/:title/index.md
post_asset_folder: true

seems to do the trick

psi-4ward avatar Feb 28 '17 19:02 psi-4ward

First, for @ebsen's request, the folder name _posts is hard-coding in hexo's source files:
https://github.com/hexojs/hexo/blob/master/lib/plugins/filter/new_post_path.js#L26
https://github.com/hexojs/hexo/blob/master/lib/plugins/processor/post.js#L14

I think it is possible to make above two lines customizable, but I'm not sure about its extent of the impact. So the change requires enough tests. Anyone makes patch?

Second, for @AWulkan's request, it is already possible to use subfolders under the source/_posts/:

new_post_name: :year/:month/:title.md

In this case, asset folders are named as source/_posts/:year/:month/:title/.

@psi-4ward's solution works in my environment too. In this case, asset folders are named as source/_posts/:year/:title/index/.

My environment is "Ubuntu 16.04.2 LTS" and as folows:

$ hexo version
hexo: 3.2.2
hexo-cli: 1.0.2
os: Linux 4.4.0-64-generic linux x64
http_parser: 2.7.0
node: 7.6.0
v8: 5.5.372.40
uv: 1.11.0
zlib: 1.2.11
ares: 1.10.1-DEV
modules: 51
openssl: 1.0.2k
icu: 58.2
unicode: 9.0
cldr: 30.0.3
tz: 2016j

seaoak avatar Mar 01 '17 01:03 seaoak

In my case I really don't want to have a sub-asset-folder index. The code to get the folder is here https://github.com/hexojs/hexo/blob/master/lib/models/post.js#L68

    var src = this.full_source;
    return src.substring(0, src.length - pathFn.extname(src).length) + pathFn.sep;

Sadly I couldn't find a way to customize it but came up with an asset-copy plugin:

const path = require('path');
const _ = require('lodash');
const ctx = hexo;

hexo.extend.processor.register(function(file) {
  return {path: file};
}, function(file) {
  if(path.extname(file.source) === '.md') return;
  
  // node_modules/hexo/lib/plugins/processor/post.js:L179
  const PostAsset = ctx.model('PostAsset');
  const Post = ctx.model('Post');
  const id = file.source.substring(ctx.base_dir.length).replace(/\\/g, '/');
  const doc = PostAsset.findById(id);

  if(file.type === 'delete') {
    if(doc) return doc.remove();
    return;
  }

  let posts = Post.toArray();
  let post;

  for(let i = 0, len = posts.length; i < len; i++) {
    post = posts[i];
    const asset_dir = path.dirname(post.asset_dir);

    if(_.startsWith(file.source, asset_dir)) {
      return PostAsset.save({
        _id: id,
        slug: file.source.substring(asset_dir.length),
        post: post._id,
        modified: true,
        renderable: file.params.renderable
      });
    }
  }

  if(doc) return doc.remove();
});

Anyone knows a better way?

psi-4ward avatar Mar 01 '17 09:03 psi-4ward