Hexo: Won't generate with post_asset_folder on and permalink ending with ".html"

Created on 3 Sep 2016  ·  10Comments  ·  Source: hexojs/hexo

Environment Info

Node version(node -v)

v6.5.0

Your site _config.yml

# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title: 御宅型
subtitle: mogita 的技术博客
description: mogita 的技术博客
author: mogita
language: zh-CN
timezone: Asia/Shanghai

# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://otaku.mogita.com
root: /
permalink: :year/:month/:title.html
permalink_defaults:

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :year-:month-:day-:title.md
default_layout: post
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
filename_case: 0
render_drafts: false
post_asset_folder: true
relative_link: false
future: true
highlight:
  enable: true
  line_number: true
  auto_detect: false
  tab_replace:

# Category & Tag
default_category: uncategorized
category_map:
tag_map:

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: clean-blog

#### Analytics
cnzz: true

feed:
  type: atom
  path: atom.xml
  limit: 20
  hub:

Your theme _config.yml

# Header
menu:
  关于: /about

# Title on top left of menu. Leave empty to use main blog title
menu_title: 

# URL of the Home page image
index_cover: /img/header.jpg

# Default post title
default_post_title: Untitled

# Comments. Choose one by filling up the information
comments:
  # Disqus comments
  disqus_shortname: otaku-mogita

# Google Analytics Tracking ID
google_analytics:

# Addthis ID
addthis:

# Social Accounts
twitter_url: https://twitter.com/mogita
twitter_handle:
facebook_url:
github_url: https://github.com/mogita
gitlab_url:
linkedin_url:
mailto:

Plugin version(npm ls --depth 0)

[email protected] /Users/mogita/Documents/Dev/otaku_blog
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

For BUG

  • Generation always fails with a fatal error ENOTDIR
  • To reproduce this, set post_asset_folder: true and permalink: :year/:month/:title.html in Hexo's _config.yml. Then hexo new a-new-post, put an image into the folder a-new-post created by hexo's new command. To change or not the a-new-post.md file is not essential. Now hexo generate and the error should emerge.

Thank you for reading thru, looking forward to a solution.

bug

All 10 comments

I am met this problem too, did you find the way to resolve this ?

@mogita I am already solved this problem; I midified the file post_asset.js in path hexo/lib/models/post_asset.js; my code is:

  PostAsset.virtual('path').get(function() {
    var Post = ctx.model('Post');
    var post = Post.findById(this.post);
    if (!post) return;
    // PostAsset.path is file path relative to `public_dir`
    // no need to urlescape, #1562
      //如果生成的文章路径是以html结尾的, 如:  2016/10/13/byte-order.html,
      // 则对应的资源路径应该是: 2016/10/13/byte-order + this.slug
      var reg = new RegExp("html" + "$");
      if(reg.test(post.path)) {
          var assetPath = post.path.substr(0, post.path.lastIndexOf("."));
          return pathFn.join(assetPath, this.slug);
      }
      return pathFn.join(post.path, this.slug);
  });

you can try it!

Hi @leokongwq

Thanks for the solution. I haven't tried your code yet, but I assume it will only process the slugs ending with "html", am I right? What if the permalink ends with, say, ".eva"? (This one was used on my wordpress blog in the past years :D)

If the permalink is set to :title.html, then a file named :title.html will be generated in public directory. Then, the path of the post assert is :title.html/post_asset_relative_path, so, it needs a directory named :title.html, but the file with same name is exist. In brief, the path of the post assert should not be prefixed with the post path.

Maybe, the pathFn.join('_' + post.path, this.slug); is better.

This needs a fix, running into the same issue.
Even if you only use permalink: :year/:month/:title.html in the config file, the blog posts are all /year/month/title/ not /year/month/title.html

This is helpful for being able to migrate from other blogging platforms like blogger.

Today, I find if the path segment is begin with _, a 404 error will happen on the github pages. So the below code will be better:

File: lib/models/post_asset.js:

var postPath = post.path;
if (/\.html$/.test(postPath)) {
  postPath = postPath.slice(0, postPath.lastIndexOf('.'));
}
return pathFn.join(postPath, this.slug);

@Alex1990 Could you please create a PR for it?

@NoahDragon Yes. But I don't understand how to implement a test for it. How to mock the post.path?

@Alex1990 Thanks. Hmmm... I see the problem. I'm also not familiar with that part. I will take a look.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Helihua1992 picture Helihua1992  ·  3Comments

demurgos picture demurgos  ·  3Comments

leoli-dev picture leoli-dev  ·  3Comments

netcan picture netcan  ·  3Comments

hjmJhon picture hjmJhon  ·  3Comments