bunto-import 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -21
  3. data/README.markdown +33 -33
  4. data/lib/bunto-import.rb +49 -49
  5. data/lib/bunto-import/importer.rb +26 -26
  6. data/lib/bunto-import/importers.rb +10 -10
  7. data/lib/bunto-import/importers/behance.rb +80 -80
  8. data/lib/bunto-import/importers/blogger.rb +330 -264
  9. data/lib/bunto-import/importers/csv.rb +96 -96
  10. data/lib/bunto-import/importers/drupal6.rb +53 -139
  11. data/lib/bunto-import/importers/drupal7.rb +54 -111
  12. data/lib/bunto-import/importers/drupal_common.rb +157 -0
  13. data/lib/bunto-import/importers/easyblog.rb +96 -96
  14. data/lib/bunto-import/importers/enki.rb +74 -74
  15. data/lib/bunto-import/importers/ghost.rb +68 -68
  16. data/lib/bunto-import/importers/google_reader.rb +64 -64
  17. data/lib/bunto-import/importers/joomla.rb +92 -90
  18. data/lib/bunto-import/importers/joomla3.rb +91 -91
  19. data/lib/bunto-import/importers/jrnl.rb +125 -125
  20. data/lib/bunto-import/importers/marley.rb +72 -72
  21. data/lib/bunto-import/importers/mephisto.rb +99 -99
  22. data/lib/bunto-import/importers/mt.rb +257 -257
  23. data/lib/bunto-import/importers/posterous.rb +130 -130
  24. data/lib/bunto-import/importers/rss.rb +62 -62
  25. data/lib/bunto-import/importers/s9y.rb +60 -60
  26. data/lib/bunto-import/importers/s9y_database.rb +363 -0
  27. data/lib/bunto-import/importers/textpattern.rb +70 -70
  28. data/lib/bunto-import/importers/tumblr.rb +300 -289
  29. data/lib/bunto-import/importers/typo.rb +88 -88
  30. data/lib/bunto-import/importers/wordpress.rb +372 -372
  31. data/lib/bunto-import/importers/wordpressdotcom.rb +207 -207
  32. data/lib/bunto-import/util.rb +76 -76
  33. data/lib/bunto-import/version.rb +3 -3
  34. data/lib/bunto/commands/import.rb +79 -79
  35. metadata +84 -54
@@ -1,68 +1,68 @@
1
- module BuntoImport
2
- module Importers
3
- class Ghost < Importer
4
-
5
- def self.specify_options(c)
6
- c.option 'dbfile', '--dbfile', 'Database file (default: ghost.db)'
7
- end
8
-
9
- def self.require_deps
10
- BuntoImport.require_with_fallback(%w[
11
- rubygems
12
- sequel
13
- fileutils
14
- safe_yaml
15
- ])
16
- end
17
-
18
- def self.process(options)
19
- posts = fetch_posts(options.fetch('dbfile', 'ghost.db'))
20
- if !posts.empty?
21
- FileUtils.mkdir_p("_posts")
22
- FileUtils.mkdir_p("_drafts")
23
- posts.each do |post|
24
- write_post_to_file(post)
25
- end
26
- end
27
- end
28
-
29
- private
30
- def self.fetch_posts(dbfile)
31
- db = Sequel.sqlite(dbfile)
32
- query = "SELECT `title`, `slug`, `markdown`, `created_at`, `status` FROM posts"
33
- db[query]
34
- end
35
-
36
- def self.write_post_to_file(post)
37
- # detect if the post is a draft
38
- draft = post[:status].eql?('draft')
39
-
40
- # Ghost saves the time in an weird format with 3 more numbers.
41
- # But the time is correct when we remove the last 3 numbers.
42
- date = Time.at(post[:created_at].to_i.to_s[0..-4].to_i)
43
-
44
- # the directory where the file will be saved to. either _drafts or _posts
45
- directory = draft ? "_drafts" : "_posts"
46
-
47
- # the filename under which the post is stored
48
- filename = File.join(directory, "#{date.strftime('%Y-%m-%d')}-#{post[:slug]}.markdown")
49
-
50
- # the YAML FrontMatter
51
- frontmatter = { 'layout' => 'post', 'title' => post[:title] }
52
- frontmatter['date'] = date if !draft # only add the date to the frontmatter when the post is published
53
- frontmatter.delete_if { |k,v| v.nil? || v == '' } # removes empty fields
54
-
55
- # write the posts to disk
56
- write_file(filename, frontmatter.to_yaml, post[:markdown])
57
- end
58
-
59
- def self.write_file(filename, frontmatter, content)
60
- File.open(filename, "w") do |f|
61
- f.puts frontmatter
62
- f.puts "---"
63
- f.puts content
64
- end
65
- end
66
- end
67
- end
68
- end
1
+ module BuntoImport
2
+ module Importers
3
+ class Ghost < Importer
4
+
5
+ def self.specify_options(c)
6
+ c.option 'dbfile', '--dbfile', 'Database file (default: ghost.db)'
7
+ end
8
+
9
+ def self.require_deps
10
+ BuntoImport.require_with_fallback(%w[
11
+ rubygems
12
+ sequel
13
+ fileutils
14
+ safe_yaml
15
+ ])
16
+ end
17
+
18
+ def self.process(options)
19
+ posts = fetch_posts(options.fetch('dbfile', 'ghost.db'))
20
+ if !posts.empty?
21
+ FileUtils.mkdir_p("_posts")
22
+ FileUtils.mkdir_p("_drafts")
23
+ posts.each do |post|
24
+ write_post_to_file(post)
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+ def self.fetch_posts(dbfile)
31
+ db = Sequel.sqlite(dbfile)
32
+ query = "SELECT `title`, `slug`, `markdown`, `created_at`, `status` FROM posts"
33
+ db[query]
34
+ end
35
+
36
+ def self.write_post_to_file(post)
37
+ # detect if the post is a draft
38
+ draft = post[:status].eql?('draft')
39
+
40
+ # Ghost saves the time in an weird format with 3 more numbers.
41
+ # But the time is correct when we remove the last 3 numbers.
42
+ date = Time.at(post[:created_at].to_i.to_s[0..-4].to_i)
43
+
44
+ # the directory where the file will be saved to. either _drafts or _posts
45
+ directory = draft ? "_drafts" : "_posts"
46
+
47
+ # the filename under which the post is stored
48
+ filename = File.join(directory, "#{date.strftime('%Y-%m-%d')}-#{post[:slug]}.markdown")
49
+
50
+ # the YAML FrontMatter
51
+ frontmatter = { 'layout' => 'post', 'title' => post[:title] }
52
+ frontmatter['date'] = date if !draft # only add the date to the frontmatter when the post is published
53
+ frontmatter.delete_if { |k,v| v.nil? || v == '' } # removes empty fields
54
+
55
+ # write the posts to disk
56
+ write_file(filename, frontmatter.to_yaml, post[:markdown])
57
+ end
58
+
59
+ def self.write_file(filename, frontmatter, content)
60
+ File.open(filename, "w") do |f|
61
+ f.puts frontmatter
62
+ f.puts "---"
63
+ f.puts content
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,64 +1,64 @@
1
- module BuntoImport
2
- module Importers
3
- class GoogleReader < Importer
4
- def self.validate(options)
5
- if options['source'].nil?
6
- abort "Missing mandatory option --source."
7
- end
8
- end
9
-
10
- def self.specify_options(c)
11
- c.option 'source', '--source', 'Source XML file of Google Reader export'
12
- end
13
-
14
- def self.require_deps
15
- BuntoImport.require_with_fallback(%w[
16
- rubygems
17
- rss
18
- fileutils
19
- safe_yaml
20
- open-uri
21
- rexml/document
22
- date
23
- ])
24
- end
25
-
26
- # Process the import.
27
- #
28
- # source - a URL or a local file String.
29
- #
30
- # Returns nothing.
31
- def self.process(options)
32
- source = options.fetch('source')
33
-
34
- open(source) do |content|
35
- feed = RSS::Parser.parse(content)
36
-
37
- raise "There doesn't appear to be any RSS items at the source (#{source}) provided." unless feed
38
-
39
- feed.items.each do |item|
40
- title = item.title.content.to_s
41
- formatted_date = Date.parse(item.published.to_s)
42
- post_name = title.split(%r{ |!|/|:|&|-|$|,}).map do |i|
43
- i.downcase if i != ''
44
- end.compact.join('-')
45
- name = "#{formatted_date}-#{post_name}"
46
-
47
- header = {
48
- 'layout' => 'post',
49
- 'title' => title
50
- }
51
-
52
- FileUtils.mkdir_p("_posts")
53
-
54
- File.open("_posts/#{name}.html", "w") do |f|
55
- f.puts header.to_yaml
56
- f.puts "---\n\n"
57
- f.puts item.content.content.to_s
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
1
+ module BuntoImport
2
+ module Importers
3
+ class GoogleReader < Importer
4
+ def self.validate(options)
5
+ if options['source'].nil?
6
+ abort "Missing mandatory option --source."
7
+ end
8
+ end
9
+
10
+ def self.specify_options(c)
11
+ c.option 'source', '--source', 'Source XML file of Google Reader export'
12
+ end
13
+
14
+ def self.require_deps
15
+ BuntoImport.require_with_fallback(%w[
16
+ rubygems
17
+ rss
18
+ fileutils
19
+ safe_yaml
20
+ open-uri
21
+ rexml/document
22
+ date
23
+ ])
24
+ end
25
+
26
+ # Process the import.
27
+ #
28
+ # source - a URL or a local file String.
29
+ #
30
+ # Returns nothing.
31
+ def self.process(options)
32
+ source = options.fetch('source')
33
+
34
+ open(source) do |content|
35
+ feed = RSS::Parser.parse(content)
36
+
37
+ raise "There doesn't appear to be any RSS items at the source (#{source}) provided." unless feed
38
+
39
+ feed.items.each do |item|
40
+ title = item.title.content.to_s
41
+ formatted_date = Date.parse(item.published.to_s)
42
+ post_name = title.split(%r{ |!|/|:|&|-|$|,}).map do |i|
43
+ i.downcase if i != ''
44
+ end.compact.join('-')
45
+ name = "#{formatted_date}-#{post_name}"
46
+
47
+ header = {
48
+ 'layout' => 'post',
49
+ 'title' => title
50
+ }
51
+
52
+ FileUtils.mkdir_p("_posts")
53
+
54
+ File.open("_posts/#{name}.html", "w") do |f|
55
+ f.puts header.to_yaml
56
+ f.puts "---\n\n"
57
+ f.puts item.content.content.to_s
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,90 +1,92 @@
1
- module BuntoImport
2
- module Importers
3
- class Joomla < Importer
4
- def self.validate(options)
5
- %w[dbname user].each do |option|
6
- if options[option].nil?
7
- abort "Missing mandatory option --#{option}."
8
- end
9
- end
10
- end
11
-
12
- def self.specify_options(c)
13
- c.option 'dbname', '--dbname', 'Database name'
14
- c.option 'user', '--user', 'Database user name'
15
- c.option 'password', '--password', "Database user's password (default: '')"
16
- c.option 'host', '--host', 'Database host name'
17
- c.option 'section', '--section', 'Table prefix name'
18
- c.option 'prefix', '--prefix', 'Table prefix name'
19
- end
20
-
21
- def self.require_deps
22
- BuntoImport.require_with_fallback(%w[
23
- rubygems
24
- sequel
25
- fileutils
26
- safe_yaml
27
- ])
28
- end
29
-
30
- def self.process(options)
31
- dbname = options.fetch('dbname')
32
- user = options.fetch('user')
33
- pass = options.fetch('password', '')
34
- host = options.fetch('host', "localhost")
35
- section = options.fetch('section', '1')
36
- table_prefix = options.fetch('prefix', "jos_")
37
-
38
- db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
39
-
40
- FileUtils.mkdir_p("_posts")
41
-
42
- # Reads a MySQL database via Sequel and creates a post file for each
43
- # post in wp_posts that has post_status = 'publish'. This restriction is
44
- # made because 'draft' posts are not guaranteed to have valid dates.
45
- query = "SELECT `title`, `alias`, CONCAT(`introtext`,`fulltext`) as content, `created`, `id` FROM #{table_prefix}content WHERE (state = '0' OR state = '1') AND sectionid = '#{section}'"
46
-
47
- db[query].each do |post|
48
- # Get required fields and construct Bunto compatible name.
49
- title = post[:title]
50
- date = post[:created]
51
- content = post[:content]
52
- id = post[:id]
53
-
54
- # Construct a slug from the title if alias field empty.
55
- # Remove illegal filename characters.
56
- if !post[:alias] or post[:alias].empty?
57
- slug = sluggify(post[:title])
58
- else
59
- slug = sluggify(post[:alias])
60
- end
61
-
62
- name = "%02d-%02d-%02d-%03d-%s.markdown" % [date.year, date.month, date.day,
63
- id,slug]
64
-
65
- # Get the relevant fields as a hash, delete empty fields and convert
66
- # to YAML for the header.
67
- data = {
68
- 'layout' => 'post',
69
- 'title' => title.to_s,
70
- 'joomla_id' => post[:id],
71
- 'joomla_url' => post[:alias],
72
- 'date' => date
73
- }.delete_if { |k,v| v.nil? || v == '' }.to_yaml
74
-
75
- # Write out the data and content to file
76
- File.open("_posts/#{name}", "w") do |f|
77
- f.puts data
78
- f.puts "---"
79
- f.puts content
80
- end
81
- end
82
- end
83
-
84
- # Borrowed from the Wordpress importer
85
- def self.sluggify( title )
86
- title = title.downcase.gsub(/[^0-9A-Za-z]+/, " ").strip.gsub(" ", "-")
87
- end
88
- end
89
- end
90
- end
1
+ module BuntoImport
2
+ module Importers
3
+ class Joomla < Importer
4
+ def self.validate(options)
5
+ %w[dbname user].each do |option|
6
+ if options[option].nil?
7
+ abort "Missing mandatory option --#{option}."
8
+ end
9
+ end
10
+ end
11
+
12
+ def self.specify_options(c)
13
+ c.option 'dbname', '--dbname', 'Database name'
14
+ c.option 'user', '--user', 'Database user name'
15
+ c.option 'password', '--password', "Database user's password (default: '')"
16
+ c.option 'host', '--host', 'Database host name'
17
+ c.option 'section', '--section', 'Table prefix name'
18
+ c.option 'prefix', '--prefix', 'Table prefix name'
19
+ end
20
+
21
+ def self.require_deps
22
+ BuntoImport.require_with_fallback(%w[
23
+ rubygems
24
+ sequel
25
+ mysql2
26
+ fileutils
27
+ safe_yaml
28
+ mysql
29
+ ])
30
+ end
31
+
32
+ def self.process(options)
33
+ dbname = options.fetch('dbname')
34
+ user = options.fetch('user')
35
+ pass = options.fetch('password', '')
36
+ host = options.fetch('host', "localhost")
37
+ section = options.fetch('section', '1')
38
+ table_prefix = options.fetch('prefix', "jos_")
39
+
40
+ db = Sequel.mysql2(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
41
+
42
+ FileUtils.mkdir_p("_posts")
43
+
44
+ # Reads a MySQL database via Sequel and creates a post file for each
45
+ # post in wp_posts that has post_status = 'publish'. This restriction is
46
+ # made because 'draft' posts are not guaranteed to have valid dates.
47
+ query = "SELECT `title`, `alias`, CONCAT(`introtext`,`fulltext`) as content, `created`, `id` FROM #{table_prefix}content WHERE (state = '0' OR state = '1') AND sectionid = '#{section}'"
48
+
49
+ db[query].each do |post|
50
+ # Get required fields and construct Bunto compatible name.
51
+ title = post[:title]
52
+ date = post[:created]
53
+ content = post[:content]
54
+ id = post[:id]
55
+
56
+ # Construct a slug from the title if alias field empty.
57
+ # Remove illegal filename characters.
58
+ if !post[:alias] or post[:alias].empty?
59
+ slug = sluggify(post[:title])
60
+ else
61
+ slug = sluggify(post[:alias])
62
+ end
63
+
64
+ name = "%02d-%02d-%02d-%03d-%s.markdown" % [date.year, date.month, date.day,
65
+ id,slug]
66
+
67
+ # Get the relevant fields as a hash, delete empty fields and convert
68
+ # to YAML for the header.
69
+ data = {
70
+ 'layout' => 'post',
71
+ 'title' => title.to_s,
72
+ 'joomla_id' => post[:id],
73
+ 'joomla_url' => post[:alias],
74
+ 'date' => date
75
+ }.delete_if { |k,v| v.nil? || v == '' }.to_yaml
76
+
77
+ # Write out the data and content to file
78
+ File.open("_posts/#{name}", "w") do |f|
79
+ f.puts data
80
+ f.puts "---"
81
+ f.puts content
82
+ end
83
+ end
84
+ end
85
+
86
+ # Borrowed from the Wordpress importer
87
+ def self.sluggify( title )
88
+ title = title.downcase.gsub(/[^0-9A-Za-z]+/, " ").strip.gsub(" ", "-")
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,91 +1,91 @@
1
- module BuntoImport
2
- module Importers
3
- class Joomla3 < Importer
4
- def self.validate(options)
5
- %w[dbname user prefix].each do |option|
6
- if options[option].nil?
7
- abort "Missing mandatory option --#{option}."
8
- end
9
- end
10
- end
11
-
12
- def self.specify_options(c)
13
- c.option 'dbname', '--dbname', 'Database name'
14
- c.option 'user', '--user', 'Database user name'
15
- c.option 'password', '--password', "Database user's password (default: '')"
16
- c.option 'host', '--host', 'Database host name'
17
- c.option 'category', '--category', 'ID of the category'
18
- c.option 'prefix', '--prefix', 'Table prefix name'
19
- end
20
-
21
- def self.require_deps
22
- BuntoImport.require_with_fallback(%w[
23
- rubygems
24
- sequel
25
- fileutils
26
- safe_yaml
27
- ])
28
- end
29
-
30
- def self.process(options)
31
- dbname = options.fetch('dbname')
32
- user = options.fetch('user')
33
- pass = options.fetch('password', '')
34
- host = options.fetch('host', "localhost")
35
- cid = options.fetch('category', 0)
36
- table_prefix = options.fetch('prefix', "jos_")
37
-
38
- db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
39
-
40
- FileUtils.mkdir_p("_posts")
41
-
42
- # Reads a MySQL database via Sequel and creates a post file for each
43
- # post in #__content that is published.
44
- query = "SELECT `cn`.`title`, `cn`.`alias`, `cn`.`introtext`, CONCAT(`cn`.`introtext`,`cn`.`fulltext`) AS `content`, "
45
- query << "`cn`.`created`, `cn`.`id`, `ct`.`title` AS `category`, `u`.`name` AS `author` "
46
- query << "FROM `#{table_prefix}content` AS `cn` JOIN `#{table_prefix}categories` AS `ct` ON `cn`.`catid` = `ct`.`id` "
47
- query << "JOIN `#{table_prefix}users` AS `u` ON `cn`.`created_by` = `u`.`id` "
48
- query << "WHERE (`cn`.`state` = '1' OR `cn`.`state` = '2') " # Only published and archived content items to be imported
49
-
50
- if cid > 0
51
- query << " AND `cn`.`catid` = '#{cid}' "
52
- else
53
- query << " AND `cn`.`catid` != '2' " #Filter out uncategorized content
54
- end
55
-
56
- db[query].each do |post|
57
- # Get required fields and construct Bunto compatible name.
58
- title = post[:title]
59
- slug = post[:alias]
60
- date = post[:created]
61
- author = post[:author]
62
- category = post[:category]
63
- content = post[:content]
64
- excerpt = post[:introtext]
65
- name = "%02d-%02d-%02d-%s.markdown" % [date.year, date.month, date.day,
66
- slug]
67
-
68
- # Get the relevant fields as a hash, delete empty fields and convert
69
- # to YAML for the header.
70
- data = {
71
- 'layout' => 'post',
72
- 'title' => title.to_s,
73
- 'joomla_id' => post[:id],
74
- 'joomla_url' => slug,
75
- 'date' => date,
76
- 'author' => author,
77
- 'excerpt' => excerpt.strip.to_s,
78
- 'category' => category
79
- }.delete_if { |k,v| v.nil? || v == '' }.to_yaml
80
-
81
- # Write out the data and content to file
82
- File.open("_posts/#{name}", "w") do |f|
83
- f.puts data
84
- f.puts "---"
85
- f.puts content
86
- end
87
- end
88
- end
89
- end
90
- end
91
- end
1
+ module BuntoImport
2
+ module Importers
3
+ class Joomla3 < Importer
4
+ def self.validate(options)
5
+ %w[dbname user prefix].each do |option|
6
+ if options[option].nil?
7
+ abort "Missing mandatory option --#{option}."
8
+ end
9
+ end
10
+ end
11
+
12
+ def self.specify_options(c)
13
+ c.option 'dbname', '--dbname', 'Database name'
14
+ c.option 'user', '--user', 'Database user name'
15
+ c.option 'password', '--password', "Database user's password (default: '')"
16
+ c.option 'host', '--host', 'Database host name'
17
+ c.option 'category', '--category', 'ID of the category'
18
+ c.option 'prefix', '--prefix', 'Table prefix name'
19
+ end
20
+
21
+ def self.require_deps
22
+ BuntoImport.require_with_fallback(%w[
23
+ rubygems
24
+ sequel
25
+ fileutils
26
+ safe_yaml
27
+ ])
28
+ end
29
+
30
+ def self.process(options)
31
+ dbname = options.fetch('dbname')
32
+ user = options.fetch('user')
33
+ pass = options.fetch('password', '')
34
+ host = options.fetch('host', "localhost")
35
+ cid = options.fetch('category', 0)
36
+ table_prefix = options.fetch('prefix', "jos_")
37
+
38
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
39
+
40
+ FileUtils.mkdir_p("_posts")
41
+
42
+ # Reads a MySQL database via Sequel and creates a post file for each
43
+ # post in #__content that is published.
44
+ query = "SELECT `cn`.`title`, `cn`.`alias`, `cn`.`introtext`, CONCAT(`cn`.`introtext`,`cn`.`fulltext`) AS `content`, "
45
+ query << "`cn`.`created`, `cn`.`id`, `ct`.`title` AS `category`, `u`.`name` AS `author` "
46
+ query << "FROM `#{table_prefix}content` AS `cn` JOIN `#{table_prefix}categories` AS `ct` ON `cn`.`catid` = `ct`.`id` "
47
+ query << "JOIN `#{table_prefix}users` AS `u` ON `cn`.`created_by` = `u`.`id` "
48
+ query << "WHERE (`cn`.`state` = '1' OR `cn`.`state` = '2') " # Only published and archived content items to be imported
49
+
50
+ if cid > 0
51
+ query << " AND `cn`.`catid` = '#{cid}' "
52
+ else
53
+ query << " AND `cn`.`catid` != '2' " #Filter out uncategorized content
54
+ end
55
+
56
+ db[query].each do |post|
57
+ # Get required fields and construct Bunto compatible name.
58
+ title = post[:title]
59
+ slug = post[:alias]
60
+ date = post[:created]
61
+ author = post[:author]
62
+ category = post[:category]
63
+ content = post[:content]
64
+ excerpt = post[:introtext]
65
+ name = "%02d-%02d-%02d-%s.markdown" % [date.year, date.month, date.day,
66
+ slug]
67
+
68
+ # Get the relevant fields as a hash, delete empty fields and convert
69
+ # to YAML for the header.
70
+ data = {
71
+ 'layout' => 'post',
72
+ 'title' => title.to_s,
73
+ 'joomla_id' => post[:id],
74
+ 'joomla_url' => slug,
75
+ 'date' => date,
76
+ 'author' => author,
77
+ 'excerpt' => excerpt.strip.to_s,
78
+ 'category' => category
79
+ }.delete_if { |k,v| v.nil? || v == '' }.to_yaml
80
+
81
+ # Write out the data and content to file
82
+ File.open("_posts/#{name}", "w") do |f|
83
+ f.puts data
84
+ f.puts "---"
85
+ f.puts content
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end