New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented `write` command. #1148

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
10 participants
@Schoonology

Schoonology commented May 25, 2013

Implemented write command.

jekyll write [type] creates a new post, page, or draft depending on [type]. It supports option for --path, --title, and --ext.

See jekyll help write.

@Schoonology

This comment has been minimized.

Show comment
Hide comment
@Schoonology

Schoonology May 25, 2013

This is the implementation of #567 .

Any feedback is greatly appreciated. I'm expecting a dialogue before this is accepted, and will be disappointed if it's accepted as-is. 😄

Schoonology commented May 25, 2013

This is the implementation of #567 .

Any feedback is greatly appreciated. I'm expecting a dialogue before this is accepted, and will be disappointed if it's accepted as-is. 😄

@parkr

View changes

Show outdated Hide outdated lib/jekyll/commands/write.rb Outdated
@parkr

View changes

Show outdated Hide outdated lib/jekyll/commands/write.rb Outdated
@parkr

View changes

Show outdated Hide outdated lib/jekyll/commands/write.rb Outdated
@parkr

View changes

Show outdated Hide outdated lib/jekyll/commands/write.rb Outdated
@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr May 25, 2013

Member

Great first draft! Thanks for putting this together. 😄

Maybe it's my comfort with rails generators, but I think it would be better to specify a type instead of a title for the arg:

$ jekyll write post --title "My Awesome Post"
# => creates ./_posts/2013-05-25-my-awesome-post.markdown with the given title in the YFM
$ jekyll write page --path "docs/v1.0.3-upgrading.md" [--title "Upgrading to v1.0.3"]
# => creates ./docs/v1.0.3-upgrading.md with the given title in the YAML Front-Matter
$ jekyll write draft --title "My Awesome Draft"
# => creates ./_drafts/my-awesome-post.markdown
Member

parkr commented May 25, 2013

Great first draft! Thanks for putting this together. 😄

Maybe it's my comfort with rails generators, but I think it would be better to specify a type instead of a title for the arg:

$ jekyll write post --title "My Awesome Post"
# => creates ./_posts/2013-05-25-my-awesome-post.markdown with the given title in the YFM
$ jekyll write page --path "docs/v1.0.3-upgrading.md" [--title "Upgrading to v1.0.3"]
# => creates ./docs/v1.0.3-upgrading.md with the given title in the YAML Front-Matter
$ jekyll write draft --title "My Awesome Draft"
# => creates ./_drafts/my-awesome-post.markdown
@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr May 25, 2013

Member

Oh, and to address your comments on #567 (sorry, i didn't see them until just a second ago), while interactive is less fragile, it isn't consistent with our other options. Every other command just does what it's told or fails if it doesn't have enough information. I'd love to keep that behaviour consistent.

Member

parkr commented May 25, 2013

Oh, and to address your comments on #567 (sorry, i didn't see them until just a second ago), while interactive is less fragile, it isn't consistent with our other options. Every other command just does what it's told or fails if it doesn't have enough information. I'd love to keep that behaviour consistent.

@Schoonology

This comment has been minimized.

Show comment
Hide comment
@Schoonology

Schoonology May 26, 2013

Updated with all of the inline feedback. I just noticed your comment about generating with a type arg rather than a title arg. If it's desired, I can change what's currently working. I chose to go by title because I think that's both the average case and the most painful: generating a new, properly-dated post file.

At least, it's my understanding that generating posts and drafts thereof will happen more frequently than pages. Is that not the case?

Schoonology commented May 26, 2013

Updated with all of the inline feedback. I just noticed your comment about generating with a type arg rather than a title arg. If it's desired, I can change what's currently working. I chose to go by title because I think that's both the average case and the most painful: generating a new, properly-dated post file.

At least, it's my understanding that generating posts and drafts thereof will happen more frequently than pages. Is that not the case?

@mattr-

This comment has been minimized.

Show comment
Hide comment
@mattr-

mattr- May 29, 2013

Member

👍 to generating a type of post and making title an option. The type portion can be optional though and should default to post.

Member

mattr- commented May 29, 2013

👍 to generating a type of post and making title an option. The type portion can be optional though and should default to post.

@mattr-

This comment has been minimized.

Show comment
Hide comment
@mattr-

mattr- May 29, 2013

Member

As far as the code goes, there needs to be a bit of refactoring done here, IMHO. There's operations going on at two levels of abstraction and the lower level isn't being named. I think there needs to be a clearer separation between the code that handles the options vs. the code that actually does the creation of the posts. I'm happy to guide you through this, but I'd like to see what you come up with first. 😃

Member

mattr- commented May 29, 2013

As far as the code goes, there needs to be a bit of refactoring done here, IMHO. There's operations going on at two levels of abstraction and the lower level isn't being named. I think there needs to be a clearer separation between the code that handles the options vs. the code that actually does the creation of the posts. I'm happy to guide you through this, but I'd like to see what you come up with first. 😃

Implemented `write` command.
`jekyll write [type]` creates a new post, page, or draft depending on [type]. It supports option for --path, --title, and --ext.

See `jekyll help write`.
@Schoonology

This comment has been minimized.

Show comment
Hide comment
@Schoonology

Schoonology May 31, 2013

Updated. Changing from jekyll write [title] to jekyll write [type] simplified the arguments required (and, therefore, the structure) considerably.

Schoonology commented May 31, 2013

Updated. Changing from jekyll write [title] to jekyll write [type] simplified the arguments required (and, therefore, the structure) considerably.

@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr May 31, 2013

Member

Great! Thanks :)

Member

parkr commented May 31, 2013

Great! Thanks :)

@scribu

This comment has been minimized.

Show comment
Hide comment
@scribu

scribu Jun 8, 2013

Contributor

I took jekyll write for a spin.

Expected workflow:

  1. I run jekyll write draft --title 'My New Idea'
  2. Jekyll creates a file at _drafts/my-new-idea.md
  3. Jekyll runs $EDITOR _drafts/my-new-idea.md

Current workflow:

  1. I run jekyll write draft --title 'My New Idea'
  2. Jekyll creates a file at _drafts/my-new-idea.markdown
  3. I run ls _drafts
  4. I run $EDITOR _drafts/my-new-idea.markdown
Contributor

scribu commented Jun 8, 2013

I took jekyll write for a spin.

Expected workflow:

  1. I run jekyll write draft --title 'My New Idea'
  2. Jekyll creates a file at _drafts/my-new-idea.md
  3. Jekyll runs $EDITOR _drafts/my-new-idea.md

Current workflow:

  1. I run jekyll write draft --title 'My New Idea'
  2. Jekyll creates a file at _drafts/my-new-idea.markdown
  3. I run ls _drafts
  4. I run $EDITOR _drafts/my-new-idea.markdown
@Schoonology

This comment has been minimized.

Show comment
Hide comment
@Schoonology

Schoonology Jun 8, 2013

@scribu Opening the editor was the original behaviour, and @parkr addressed it in an "outdated diff": #1148 (comment)

Schoonology commented Jun 8, 2013

@scribu Opening the editor was the original behaviour, and @parkr addressed it in an "outdated diff": #1148 (comment)

@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr Jun 8, 2013

Member

I'd love to have some output that is like

Wrote [post|page] template to <path>

@Schoonology, you'd use Jekyll.logger for that:

Jekyll.logger.info("Wrote #{type} template to #{path}", "")

The interface for the logger needs to be cleaned up a bit but for now you need that second empty string.

Member

parkr commented Jun 8, 2013

I'd love to have some output that is like

Wrote [post|page] template to <path>

@Schoonology, you'd use Jekyll.logger for that:

Jekyll.logger.info("Wrote #{type} template to #{path}", "")

The interface for the logger needs to be cleaned up a bit but for now you need that second empty string.

@scribu

This comment has been minimized.

Show comment
Hide comment
@scribu

scribu Jun 8, 2013

Contributor

I'd prefer it if it'd just output the path, since I could then easily do something like this:

jekyll write draft --title 'My New Idea' | xargs vim
Contributor

scribu commented Jun 8, 2013

I'd prefer it if it'd just output the path, since I could then easily do something like this:

jekyll write draft --title 'My New Idea' | xargs vim
@Schoonology

This comment has been minimized.

Show comment
Hide comment
@Schoonology

Schoonology Jun 8, 2013

Another option:

if STDOUT.tty?
  Jekyll.logger.info("Wrote #{type} template to #{path}", "")
else
  puts path
end

This meets both needs.

Schoonology commented Jun 8, 2013

Another option:

if STDOUT.tty?
  Jekyll.logger.info("Wrote #{type} template to #{path}", "")
else
  puts path
end

This meets both needs.

@scribu

This comment has been minimized.

Show comment
Hide comment
@scribu

scribu Jun 8, 2013

Contributor

The problem is that if you see Wrote #{type} template to #{path} when you first try it out, you wouldn't then think to pipe it to something.

Contributor

scribu commented Jun 8, 2013

The problem is that if you see Wrote #{type} template to #{path} when you first try it out, you wouldn't then think to pipe it to something.

@scribu

This comment has been minimized.

Show comment
Hide comment
@scribu

scribu Jun 8, 2013

Contributor

Other bug:

Steps to reproduce:

jekyll write draft --title 'Version 0.10' --path _drafts/version-0.10.md

Expected contents of the file:

---
title: Version 0.10
---

Actual contents:

---
title: Version
---
Contributor

scribu commented Jun 8, 2013

Other bug:

Steps to reproduce:

jekyll write draft --title 'Version 0.10' --path _drafts/version-0.10.md

Expected contents of the file:

---
title: Version 0.10
---

Actual contents:

---
title: Version
---
@Schoonology

This comment has been minimized.

Show comment
Hide comment
@Schoonology

Schoonology Jun 8, 2013

@scribu Can I get more information? I'm unable to reproduce your issue.

Schoonology commented Jun 8, 2013

@scribu Can I get more information? I'm unable to reproduce your issue.

@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr Jun 8, 2013

Member

@scribu I've used some unix programs whose output modifies depending upon the destination. If STDOUT is a program it's one way, but if it's the terminal, it's a different way. When we write documentation for this, we can describe this behaviour.

Member

parkr commented Jun 8, 2013

@scribu I've used some unix programs whose output modifies depending upon the destination. If STDOUT is a program it's one way, but if it's the terminal, it's a different way. When we write documentation for this, we can describe this behaviour.

@scribu

This comment has been minimized.

Show comment
Hide comment
@scribu

scribu Jun 8, 2013

Contributor

@scribu Can I get more information? I'm unable to reproduce your issue.

I'm on OS X 10.8.3, using iTerm 2 and running ruby 1.9.3 via bash. Any particular gem versions you would like to know?

Contributor

scribu commented Jun 8, 2013

@scribu Can I get more information? I'm unable to reproduce your issue.

I'm on OS X 10.8.3, using iTerm 2 and running ruby 1.9.3 via bash. Any particular gem versions you would like to know?

@scribu

This comment has been minimized.

Show comment
Hide comment
@scribu

scribu Jun 8, 2013

Contributor

Also, shouldn't I get some sort of warning if the file already exists?

Contributor

scribu commented Jun 8, 2013

Also, shouldn't I get some sort of warning if the file already exists?

c.option '--ext STRING', String, 'File extension to use with --title and directory paths. Default: markdown'
c.action do |args, options|
args = ['post'] if args.empty?

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

Why not require an arg?

If we don't require an arg, I'd say we should create drafts over posts.

@parkr

parkr Jun 8, 2013

Member

Why not require an arg?

If we don't require an arg, I'd say we should create drafts over posts.

path = generate_post(options)
when "page"
path = generate_page(options)
end

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

Duplication Police! Put your hands up!

path = if %w[draft page post].include?(args[0])
  send("generate_#(args[0]}", options)
else
  Jekyll.logger.warn "Invalid Argument:", "Jekyll can only write posts, pages and drafts for you. Beyond that, you're on your own."
  raise ArgumentError.new("Invalid type for writing: '#{args[0]}'")
end

(P.S. I'm crazy.)

@parkr

parkr Jun 8, 2013

Member

Duplication Police! Put your hands up!

path = if %w[draft page post].include?(args[0])
  send("generate_#(args[0]}", options)
else
  Jekyll.logger.warn "Invalid Argument:", "Jekyll can only write posts, pages and drafts for you. Beyond that, you're on your own."
  raise ArgumentError.new("Invalid type for writing: '#{args[0]}'")
end

(P.S. I'm crazy.)

This comment has been minimized.

@kelvinst

kelvinst Aug 5, 2013

Are you okay @parkr? 😆...

Jokes apart, good sugestion (=
But I think it's better if you use a { instead of ( in the send first argument, or maybe you get in trouble with the runtime error police 😆

@kelvinst

kelvinst Aug 5, 2013

Are you okay @parkr? 😆...

Jokes apart, good sugestion (=
But I think it's better if you use a { instead of ( in the send first argument, or maybe you get in trouble with the runtime error police 😆

if STDOUT.tty?
Jekyll::Stevenson.info("Wrote #{args[0]} template to #{path}", "")
else
puts path

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

I think you forgot to receive the path from your case statement :)

@parkr

parkr Jun 8, 2013

Member

I think you forgot to receive the path from your case statement :)

file.puts("---")
file.puts("title: #{title}") if title
file.puts("date: #{Time.now.strftime('%d %h %Y %H:%M:%S')}") if date
file.puts("---")

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

This is definitely good for transparency, but why not write a Hash as yaml and add the following ---?

@parkr

parkr Jun 8, 2013

Member

This is definitely good for transparency, but why not write a Hash as yaml and add the following ---?

This comment has been minimized.

@kelvinst

kelvinst Aug 5, 2013

In agree with @parkr

@kelvinst

kelvinst Aug 5, 2013

In agree with @parkr

options[:path]
else
"_drafts/#{pathify(options[:title])}.#{options[:ext]}"
end

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

There's a lot of duplication with setting the path. Can you contain that in one method which you call separately? Maybe pass them the type and options :)

@parkr

parkr Jun 8, 2013

Member

There's a lot of duplication with setting the path. Can you contain that in one method which you call separately? Maybe pass them the type and options :)

"#{pathify(options[:title])}.html"
end
if File.extname(path) === ""

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

I don't think the triple equals is what we're looking for here?

@parkr

parkr Jun 8, 2013

Member

I don't think the triple equals is what we're looking for here?

end
if File.extname(path) === ""
path = File.join(path, "index" + "." + options[:ext])

This comment has been minimized.

@parkr

parkr Jun 8, 2013

Member

interpolation 💃

path = File.join(path, "index.#{options[:ext]}")
@parkr

parkr Jun 8, 2013

Member

interpolation 💃

path = File.join(path, "index.#{options[:ext]}")
@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr Aug 5, 2013

Member

Looks like this has moved into stagnancy. Want me to start where you left off?

Member

parkr commented Aug 5, 2013

Looks like this has moved into stagnancy. Want me to start where you left off?

@robwierzbowski

This comment has been minimized.

Show comment
Hide comment
@robwierzbowski

robwierzbowski Aug 5, 2013

Contributor

Coming here from the twitter post. My wishlist for write (and something I am otherwise planning on plugin-izing when I have time) would be to define empty template files on which to base the new posts. For example

posts/
- authors/
-- author.md
-- 2013-08-05-Orhan-Pamuk.markdown
-- ...more posts
- books/
-- book.md
-- 2013-08-05-My-Name-Is-Red.markdown
-- ...more posts

Where author.md would have the head matter (and maybe even some content structure) defined for all author posts, and book.md would have the same for books. Storing the template files in a single, outside of posts folder and creating the new file with write author "title" in the CWD would be even better.

It's a little more CMS-ey though, so not sure how well it fits as a Jekyll core feature.

Contributor

robwierzbowski commented Aug 5, 2013

Coming here from the twitter post. My wishlist for write (and something I am otherwise planning on plugin-izing when I have time) would be to define empty template files on which to base the new posts. For example

posts/
- authors/
-- author.md
-- 2013-08-05-Orhan-Pamuk.markdown
-- ...more posts
- books/
-- book.md
-- 2013-08-05-My-Name-Is-Red.markdown
-- ...more posts

Where author.md would have the head matter (and maybe even some content structure) defined for all author posts, and book.md would have the same for books. Storing the template files in a single, outside of posts folder and creating the new file with write author "title" in the CWD would be even better.

It's a little more CMS-ey though, so not sure how well it fits as a Jekyll core feature.

end
if STDOUT.tty?
Jekyll::Stevenson.info("Wrote #{args[0]} template to #{path}", "")

This comment has been minimized.

@kelvinst

kelvinst Aug 5, 2013

Some reason to use directly Stevenson instead of Jekyll.logger?

@kelvinst

kelvinst Aug 5, 2013

Some reason to use directly Stevenson instead of Jekyll.logger?

This comment has been minimized.

@parkr

parkr Aug 6, 2013

Member

Maybe it was before we added Jekyll.logger - let's switch it!

@parkr

parkr Aug 6, 2013

Member

Maybe it was before we added Jekyll.logger - let's switch it!

This comment has been minimized.

@qmx

qmx Aug 7, 2013

fixed this here qmx@d4f81ca

@qmx

qmx Aug 7, 2013

fixed this here qmx@d4f81ca

@mattvh

This comment has been minimized.

Show comment
Hide comment
@mattvh

mattvh Aug 5, 2013

Contributor

I'd definitely like to see support for linkblogging. I currently use a Thor script to do this for my blog, and I have commands that work like this:

thor blog:post "Post Title"
thor blog:post "Post Title" --link "http://example.org"

The latter sets external-url in the YAML front matter, so my theme can pick it up and display the post differently. If we're getting a built-in write command, it would be nice to have that functionality built-in so I could dump the Thor script.

jekyll write post "New Post Title" --link "http://example.org"
Contributor

mattvh commented Aug 5, 2013

I'd definitely like to see support for linkblogging. I currently use a Thor script to do this for my blog, and I have commands that work like this:

thor blog:post "Post Title"
thor blog:post "Post Title" --link "http://example.org"

The latter sets external-url in the YAML front matter, so my theme can pick it up and display the post differently. If we're getting a built-in write command, it would be nice to have that functionality built-in so I could dump the Thor script.

jekyll write post "New Post Title" --link "http://example.org"
@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr Aug 7, 2013

Member

Linkposts is a good idea! I wonder how many people who use Jekyll generate linkposts.

I think in the first iteration, we'd just generate the base stuff then add templates later. I had a long conversation with @imathis about this a month or so ago and we'd have to use ERB templates or something that would allow for some amount of dynamism. Ideally:

$ jekyll write post --title TITLE [--link LINK] [--layout LAYOUT] [--ext EXT]
# generates post at _posts/2013-08-07-title.EXT like this:
#
# ---
# layout: LAYOUT # (defaults to 'default', maybe?)
# date: "2013-08-07T23:14:13+02:00"
# title: TITLE
# [link: LINK]
# ---
#

$ jekyll write page --path PATH [--title TITLE] [--layout LAYOUT]
# generates page at PATH like this:
#
# ---
# layout: LAYOUT
# title: TITLE # if provided
# ---
#

$ jekyll write post --template post --title TITLE
# reads in contents of `_write/post.erb`, runs it through ERB and outputs it to the proper place
# it would also take all the options above and set each of them as variables,
#     thus `--layout LAYOUT` is accessible via `<%= layout # outputs "LAYOUT" %>`.

# Same thing with pages.

@benbalter, you always know what to do in situations like this. What level of customization do you think is wise?

Member

parkr commented Aug 7, 2013

Linkposts is a good idea! I wonder how many people who use Jekyll generate linkposts.

I think in the first iteration, we'd just generate the base stuff then add templates later. I had a long conversation with @imathis about this a month or so ago and we'd have to use ERB templates or something that would allow for some amount of dynamism. Ideally:

$ jekyll write post --title TITLE [--link LINK] [--layout LAYOUT] [--ext EXT]
# generates post at _posts/2013-08-07-title.EXT like this:
#
# ---
# layout: LAYOUT # (defaults to 'default', maybe?)
# date: "2013-08-07T23:14:13+02:00"
# title: TITLE
# [link: LINK]
# ---
#

$ jekyll write page --path PATH [--title TITLE] [--layout LAYOUT]
# generates page at PATH like this:
#
# ---
# layout: LAYOUT
# title: TITLE # if provided
# ---
#

$ jekyll write post --template post --title TITLE
# reads in contents of `_write/post.erb`, runs it through ERB and outputs it to the proper place
# it would also take all the options above and set each of them as variables,
#     thus `--layout LAYOUT` is accessible via `<%= layout # outputs "LAYOUT" %>`.

# Same thing with pages.

@benbalter, you always know what to do in situations like this. What level of customization do you think is wise?

@imathis

This comment has been minimized.

Show comment
Hide comment
@imathis

imathis Aug 7, 2013

Contributor

@parkr, link: http://some-external-site.com in the yaml front matter looks nice. It's a bit odd when in the template, to access post.link and post.url. That's why we ended up using external-url for the Octopress link blogging feature. I really like the brevity of link and if Jekyll is going to use it, I may end up deciding to switch, but it's worth thinking about whether link is a good variable name for this.

Contributor

imathis commented Aug 7, 2013

@parkr, link: http://some-external-site.com in the yaml front matter looks nice. It's a bit odd when in the template, to access post.link and post.url. That's why we ended up using external-url for the Octopress link blogging feature. I really like the brevity of link and if Jekyll is going to use it, I may end up deciding to switch, but it's worth thinking about whether link is a good variable name for this.

@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr Aug 7, 2013

Member

@imathis external-url makes more sense in the context of writing templates. Thanks!

Member

parkr commented Aug 7, 2013

@imathis external-url makes more sense in the context of writing templates. Thanks!

@parkr parkr referenced this pull request Aug 7, 2013

Closed

Continue work on `write` command #1395

2 of 4 tasks complete
@parkr

This comment has been minimized.

Show comment
Hide comment
@parkr

parkr Aug 7, 2013

Member

Continuing work with this in #1395.

Member

parkr commented Aug 7, 2013

Continuing work with this in #1395.

@parkr parkr closed this Aug 7, 2013

This was referenced Apr 27, 2014

@jekyll jekyll locked and limited conversation to collaborators Feb 27, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.