ecrire 0.22.1 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +5 -0
  4. data/Gemfile +19 -0
  5. data/README.md +2 -0
  6. data/Rakefile +1 -1
  7. data/lib/ecrire/app/assets/javascripts/admin/editor/content.coffee +46 -76
  8. data/lib/ecrire/app/assets/javascripts/admin/editor/ext.coffee +3 -0
  9. data/lib/ecrire/app/assets/javascripts/admin/editor/extensions/clipboard.coffee +2 -1
  10. data/lib/ecrire/app/assets/javascripts/admin/editor/extensions/code.coffee +1 -2
  11. data/lib/ecrire/app/assets/javascripts/admin/editor/extensions/image.coffee +73 -1
  12. data/lib/ecrire/app/assets/javascripts/admin/editor/parsers/image.coffee +6 -115
  13. data/lib/ecrire/app/assets/javascripts/admin/editor.coffee +1 -0
  14. data/lib/ecrire/app/assets/javascripts/admin/{editor/navigation → navigation}/delete.js.coffee +1 -2
  15. data/lib/ecrire/app/assets/javascripts/admin/{editor/navigation → navigation}/draft.js.coffee +1 -3
  16. data/lib/ecrire/app/assets/javascripts/admin/{editor/navigation → navigation}/help.js.coffee +1 -1
  17. data/lib/ecrire/app/assets/javascripts/admin/{editor/navigation → navigation}/save.js.coffee +2 -2
  18. data/lib/ecrire/app/assets/javascripts/admin/{editor/navigation → navigation}/sticky.js.coffee +1 -2
  19. data/lib/ecrire/app/assets/javascripts/admin/{editor/navigation → navigation}/toggle.js.coffee +1 -2
  20. data/lib/ecrire/app/assets/javascripts/admin/posts/header.coffee +96 -40
  21. data/lib/ecrire/app/assets/javascripts/admin/posts/new.js.coffee +1 -2
  22. data/lib/ecrire/app/assets/javascripts/admin/posts/tag.js.coffee +7 -0
  23. data/lib/ecrire/app/assets/javascripts/admin/posts/tags.js.coffee +15 -0
  24. data/lib/ecrire/app/assets/javascripts/admin/posts/title.coffee +38 -9
  25. data/lib/ecrire/app/assets/javascripts/admin/tags/list.js.coffee +34 -0
  26. data/lib/ecrire/app/assets/javascripts/admin.js +1 -1
  27. data/lib/ecrire/app/assets/javascripts/application.js +2 -3
  28. data/lib/ecrire/app/assets/javascripts/shared/overlay.js.coffee +1 -2
  29. data/lib/ecrire/app/assets/javascripts/shared/popup.js.coffee +1 -2
  30. data/lib/ecrire/app/assets/stylesheets/admin/base.css.scss +1 -2
  31. data/lib/ecrire/app/assets/stylesheets/admin/editor/base.css.scss +0 -7
  32. data/lib/ecrire/app/assets/stylesheets/admin/editor/content.css.scss +30 -12
  33. data/lib/ecrire/app/assets/stylesheets/admin/editor/header.css.scss +154 -32
  34. data/lib/ecrire/app/assets/stylesheets/admin/posts.css.scss +8 -1
  35. data/lib/ecrire/app/assets/stylesheets/admin/tags.css.scss +78 -0
  36. data/lib/ecrire/app/assets/stylesheets/admin/title.css.scss +51 -0
  37. data/lib/ecrire/app/assets/stylesheets/admin/variables.css.scss +3 -0
  38. data/lib/ecrire/app/assets/stylesheets/shared/popup.css.scss +2 -0
  39. data/lib/ecrire/app/controllers/admin/application_controller.rb +6 -0
  40. data/lib/ecrire/app/controllers/admin/images_controller.rb +5 -6
  41. data/lib/ecrire/app/controllers/admin/posts/tags_controller.rb +35 -0
  42. data/lib/ecrire/app/controllers/admin/posts_controller.rb +13 -12
  43. data/lib/ecrire/app/controllers/admin/tags_controller.rb +4 -0
  44. data/lib/ecrire/app/controllers/admin/titles_controller.rb +39 -0
  45. data/lib/ecrire/app/controllers/application_controller.rb +13 -3
  46. data/lib/ecrire/app/controllers/ecrire/posts_controller.rb +6 -5
  47. data/lib/ecrire/app/helpers/posts_helper.rb +0 -12
  48. data/lib/ecrire/app/models/admin/image.rb +4 -7
  49. data/lib/ecrire/app/models/admin/post.rb +2 -7
  50. data/lib/ecrire/app/models/admin/tag.rb +4 -0
  51. data/lib/ecrire/app/models/admin/title.rb +4 -0
  52. data/lib/ecrire/app/models/post.rb +30 -22
  53. data/lib/ecrire/app/models/tag.rb +5 -0
  54. data/lib/ecrire/app/models/title.rb +62 -0
  55. data/lib/ecrire/app/views/admin/images/errors.json.jbuilder +1 -0
  56. data/lib/ecrire/app/views/admin/posts/edit.html.erb +61 -21
  57. data/lib/ecrire/app/views/admin/posts/header/_dropping.html.erb +12 -0
  58. data/lib/ecrire/app/views/admin/posts/header/_error.html.erb +18 -0
  59. data/lib/ecrire/app/views/admin/posts/header/_uploading.html.erb +21 -0
  60. data/lib/ecrire/app/views/admin/posts/new.html.erb +23 -0
  61. data/lib/ecrire/app/views/admin/posts/tags/_tag.html.erb +10 -0
  62. data/lib/ecrire/app/views/admin/posts/tags/create.js.erb +1 -0
  63. data/lib/ecrire/app/views/admin/posts/tags/dialog/_tag.html.erb +3 -0
  64. data/lib/ecrire/app/views/admin/posts/tags/dialog/_tags.html.erb +12 -0
  65. data/lib/ecrire/app/views/admin/posts/tags/index.js.erb +1 -0
  66. data/lib/ecrire/app/views/admin/posts/tags/update.js.erb +2 -0
  67. data/lib/ecrire/app/views/admin/titles/_title.html.erb +11 -0
  68. data/lib/ecrire/app/views/admin/titles/_titles.html.erb +22 -0
  69. data/lib/ecrire/app/views/admin/titles/create.js.erb +1 -0
  70. data/lib/ecrire/app/views/admin/titles/edit.js.erb +1 -0
  71. data/lib/ecrire/app/views/admin/titles/errors.js.erb +5 -0
  72. data/lib/ecrire/app/views/admin/titles/index.js.erb +1 -0
  73. data/lib/ecrire/app/views/admin/titles/update.js.erb +1 -0
  74. data/lib/ecrire/app/views/layouts/admin/application.html.erb +1 -1
  75. data/lib/ecrire/app/views/sessions/_navigation.html.erb +1 -1
  76. data/lib/ecrire/application.rb +1 -1
  77. data/lib/ecrire/config/routes.rb +2 -2
  78. data/lib/ecrire/db/migrate/20150305123321_move_labels_to_titles.rb +27 -0
  79. data/lib/ecrire/db/migrate/20150318549479_create_tags.rb +13 -0
  80. data/lib/ecrire/db/schema.rb +25 -22
  81. data/lib/ecrire/onboarding/assets/javascripts/base.js +1 -1
  82. data/lib/ecrire/onboarding/assets/javascripts/databases/information.js.coffee +1 -1
  83. data/lib/ecrire/onboarding/assets/javascripts/message.js.coffee +1 -1
  84. data/lib/ecrire/template/Gemfile +4 -3
  85. data/lib/ecrire/template/assets/javascripts/base.js.coffee +1 -0
  86. data/lib/ecrire/version.rb +1 -1
  87. data/test/editor/controllers/base_controller_test.rb +1 -0
  88. data/test/editor/models/post_test.rb +26 -56
  89. data/test/editor/models/title_test.rb +31 -0
  90. data/test/editor/test_helper.rb +2 -0
  91. data/test/fixtures/posts.yml +0 -4
  92. data/test/fixtures/tags.yml +2 -0
  93. data/test/fixtures/titles.yml +11 -0
  94. data/test/initializations/railtie_test.rb +2 -2
  95. data/test/themes/template/secrets.yml +6 -0
  96. metadata +49 -24
  97. data/lib/ecrire/app/assets/stylesheets/admin/editor/image.css.scss +0 -58
  98. data/lib/ecrire/app/controllers/admin/labels_controller.rb +0 -18
  99. data/lib/ecrire/app/models/label.rb +0 -3
  100. data/lib/ecrire/app/views/admin/images/errors.js.erb +0 -1
  101. data/lib/ecrire/app/views/admin/posts/title.html.erb +0 -10
  102. data/test/editor/controllers/admin/images_controller_test.rb +0 -6
  103. data/test/editor/controllers/admin/posts_controller_test.rb +0 -90
  104. data/test/editor/controllers/images_controller_test.rb +0 -2
  105. data/test/editor/controllers/partials_controller_test.rb +0 -2
  106. data/test/editor/controllers/posts_controller_test.rb +0 -21
  107. data/test/editor/helpers/posts_helper_test.rb +0 -3
  108. data/test/editor/models/partial_test.rb +0 -4
  109. data/test/fixtures/partials.yml +0 -9
  110. /data/lib/ecrire/app/views/admin/images/{update.js.erb → create.js.erb} +0 -0
  111. /data/{lib/ecrire/template/assets/javascripts/post.js.coffee → test/themes/onboarding/.keep} +0 -0
@@ -1,19 +1,51 @@
1
- <header>
2
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class='toggle', as='Navigation.Toggle' x="0px" y="0px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
3
- <path d="M4.516,7.548c0.436-0.446,1.043-0.481,1.576,0L10,11.295l3.908-3.747c0.533-0.481,1.141-0.446,1.574,0 c0.436,0.445,0.408,1.197,0,1.615c-0.406,0.418-4.695,4.502-4.695,4.502C10.57,13.888,10.285,14,10,14s-0.57-0.112-0.789-0.335 c0,0-4.287-4.084-4.695-4.502C4.107,8.745,4.08,7.993,4.516,7.548z"/>
4
- </svg>
5
-
6
- <%= form_for @post,
7
- as: 'post',
8
- remote: true,
9
- html: {as: 'Posts.Title', class: %w(post title settings autosave)} do |f| %>
10
- <%= hidden_field_tag :context, :title %>
11
-
12
- <%= f.text_field :title, class: %w(title), autocomplete: :off %>
1
+ <%= content_tag :header, as: "Post.Header", href: admin_post_image_path(@post), method: 'POST' do |header| %>
2
+ <template for='Post.Header'>
3
+ <%= render 'admin/posts/header/dropping', css: %w(status dropping hidden) %>
4
+ <%= render 'admin/posts/header/uploading', css: %w(status uploading hidden) %>
5
+ <%= render 'admin/posts/header/error', css: %w(status error hidden) %>
6
+ </template>
7
+
8
+ <% if @post.header? %>
9
+ <% header[:style] = "background-image: url(#{@post.header.url});" %>
13
10
  <% end %>
14
- </header>
11
+ <div class='drop'>
12
+ </div>
13
+
14
+ <div class='title'>
15
+
16
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class='toggle', as='Navigation.Toggle' x="0px" y="0px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
17
+ <path d="M4.516,7.548c0.436-0.446,1.043-0.481,1.576,0L10,11.295l3.908-3.747c0.533-0.481,1.141-0.446,1.574,0 c0.436,0.445,0.408,1.197,0,1.615c-0.406,0.418-4.695,4.502-4.695,4.502C10.57,13.888,10.285,14,10,14s-0.57-0.112-0.789-0.335 c0,0-4.287-4.084-4.695-4.502C4.107,8.745,4.08,7.993,4.516,7.548z"/>
18
+ </svg>
19
+ <%= content_tag :svg,
20
+ method: 'DELETE',
21
+ href: admin_post_image_path(@post),
22
+ class: %w(clear),
23
+ version: "1.1",
24
+ xmlns: "http://www.w3.org/2000/svg",
25
+ 'xmlns:xlink' => "http://www.w3.org/1999/xlink",
26
+ x: "0px",
27
+ y: "0px",
28
+ viewBox: "0 0 20 20",
29
+ 'enable-background' => "new 0 0 20 20",
30
+ 'xml:space' => "preserve" do |svg| %>
31
+
32
+ <% if !@post.header? %>
33
+ <% svg.css << 'hidden' %>
34
+ <% end %>
35
+
36
+ <path d="M16,2H4C2.9,2,2,2.9,2,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C18,2.9,17.1,2,16,2z M13.061,14.789L10,11.729
37
+ l-3.061,3.06l-1.729-1.728L8.271,10L5.211,6.939l1.729-1.729L10,8.271l3.059-3.061l1.729,1.729L11.729,10l3.06,3.061L13.061,14.789z
38
+ "/>
39
+ <% end %>
40
+
41
+ <%= link_to @post.title, admin_post_titles_path(@post), remote: true, class: %w(title) %>
42
+ <input type='file' />
43
+ <p class='browse'>Set a header image. Either <strong>drop</strong> an image here or <strong>select an image</strong>.</p>
44
+ </div>
45
+
46
+ <% end %>
15
47
 
16
- <section as='Post.Documentation'>
48
+ <section>
17
49
 
18
50
  <%= content_tag :div, class: %w(publish state), href: admin_post_path(@post.id), as: 'Post.Sticky' do %>
19
51
 
@@ -41,15 +73,23 @@
41
73
  <% end %>
42
74
 
43
75
  <article>
44
- <%= content_tag :header, as: "Post.Header" do |header| %>
45
- <% if @post.header? %>
46
- <% header[:style] = "background-image: url(#{@post.header.url});" %>
47
- <% end %>
48
76
 
49
- <%= render 'admin/images/form', post: @post %>
50
- <% end %>
77
+ <div id='TagsList'>
78
+ <svg version="1.1" id="Tag" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
79
+ <path d="M18.662,5.521L5.237,19l0.707-4.967l-4.945,0.709L14.424,1.263c0.391-0.392,1.133-0.308,1.412,0l2.826,2.839 C19.162,4.575,19.053,5.128,18.662,5.521z"/>
80
+ </svg>
81
+ <ul class='tags' as='Post.Tags'>
82
+ <% @post.tags.each do |tag| %>
83
+ <%= render 'admin/posts/tags/tag', tag: tag, post: @post %>
84
+ <% end %>
85
+ <%= link_to "Add tags", admin_post_tags_path(@post), remote: true %>
86
+ </ul>
87
+ </div>
51
88
 
52
89
  <%= post_edit_content(@post) %>
90
+
91
+ <template id='EditorElements'>
92
+ <figure as='Editor.Image'><template for='Editor.Image' contenteditable=false><p class='placeholder'>Drop an image or click here to upload a picture.</p><img><div class='progressbar'><span class='progress'></span></div></template><div contenteditable=false><input type='file' /></div><figcaption></figcaption></figure></template>
53
93
  </article>
54
94
 
55
95
  <div class='save' as='Post.Sticky'>
@@ -61,7 +101,7 @@
61
101
  <% end %>
62
102
  <% end %>
63
103
 
64
- <%= link_to 'Syntax', help_admin_posts_path, remote: true, class: %w(help) %>
104
+ <%= link_to 'Syntax', help_admin_posts_path, remote: true, class: %w(help), as: 'Post.Documentation' %>
65
105
 
66
106
  <% unless Rails.application.secrets.has_key?(:s3) %>
67
107
  <div class='s3 configuration missing'>
@@ -0,0 +1,12 @@
1
+ <%= content_tag :div, class: css do %>
2
+ <svg version="1.1" id="Download" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
3
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
4
+ <path d="M15,7h-3V1H8v6H5l5,5L15,7z M19.338,13.532c-0.21-0.224-1.611-1.723-2.011-2.114C17.062,11.159,16.683,11,16.285,11h-1.757
5
+ l3.064,2.994h-3.544c-0.102,0-0.194,0.052-0.24,0.133L12.992,16H7.008l-0.816-1.873c-0.046-0.081-0.139-0.133-0.24-0.133H2.408
6
+ L5.471,11H3.715c-0.397,0-0.776,0.159-1.042,0.418c-0.4,0.392-1.801,1.891-2.011,2.114c-0.489,0.521-0.758,0.936-0.63,1.449
7
+ l0.561,3.074c0.128,0.514,0.691,0.936,1.252,0.936h16.312c0.561,0,1.124-0.422,1.252-0.936l0.561-3.074
8
+ C20.096,14.468,19.828,14.053,19.338,13.532z"/>
9
+ </svg>
10
+
11
+ <p>Release the image to set it the header for this post.</p>
12
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <%= content_tag :div, class: css do %>
2
+ <svg version="1.1" id="Emoji_sad" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
3
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
4
+ <path d="M10.001,0.4C4.698,0.4,0.4,4.698,0.4,10c0,5.303,4.298,9.601,9.601,9.601c5.301,0,9.6-4.298,9.6-9.601
5
+ C19.6,4.698,15.301,0.4,10.001,0.4z M10,17.599c-4.197,0-7.6-3.402-7.6-7.6c0-4.197,3.402-7.6,7.6-7.6c4.197,0,7.6,3.402,7.6,7.6
6
+ C17.6,14.197,14.197,17.599,10,17.599z M12.501,9.75c0.828,0,1.5-0.783,1.5-1.75s-0.672-1.75-1.5-1.75c-0.828,0-1.5,0.783-1.5,1.75
7
+ S11.672,9.75,12.501,9.75z M7.501,9.75c0.828,0,1.5-0.783,1.5-1.75s-0.672-1.75-1.5-1.75c-0.828,0-1.5,0.783-1.5,1.75
8
+ S6.672,9.75,7.501,9.75z M10.002,11.25c-3.424,0-4.622,2.315-4.672,2.414c-0.186,0.371-0.035,0.821,0.335,1.007
9
+ C5.773,14.724,5.887,14.75,6,14.75c0.275,0,0.54-0.151,0.672-0.414c0.008-0.017,0.822-1.586,3.33-1.586
10
+ c2.463,0,3.298,1.527,3.328,1.585c0.184,0.37,0.635,0.523,1.006,0.336c0.371-0.184,0.521-0.636,0.336-1.006
11
+ C14.623,13.566,13.426,11.25,10.002,11.25z"/>
12
+ </svg>
13
+
14
+ <ul class='messages'>
15
+ </ul>
16
+
17
+ <button>Dismiss</button>
18
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <%= content_tag :div, class: css do %>
2
+ <svg version="1.1" id="Hour_glass" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
3
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
4
+ <path d="M15.6,4.576c0-2.139,0-2.348,0-2.348C15.6,1.439,13.092,0,10,0C6.907,0,4.4,1.439,4.4,2.228c0,0,0,0.209,0,2.348
5
+ C4.4,6.717,8.277,8.484,8.277,10c0,1.514-3.877,3.281-3.877,5.422c0,2.141,0,2.35,0,2.35C4.4,18.56,6.907,20,10,20
6
+ c3.092,0,5.6-1.44,5.6-2.229c0,0,0-0.209,0-2.35c0-2.141-3.877-3.908-3.877-5.422C11.723,8.484,15.6,6.717,15.6,4.576z M5.941,2.328
7
+ c0.696-0.439,2-1.082,4.114-1.082c2.113,0,4.006,1.082,4.006,1.082c0.142,0.086,0.698,0.383,0.317,0.609
8
+ C13.54,3.434,11.9,3.957,10,3.957c-1.9,0-3.484-0.576-4.324-1.074C5.295,2.658,5.941,2.328,5.941,2.328z M10.501,10
9
+ c0,1.193,0.996,1.961,2.051,2.986c0.771,0.748,1.826,1.773,1.826,2.435v1.328c-0.97-0.483-3.872-0.955-3.872-2.504
10
+ c0-0.783-1.013-0.783-1.013,0c0,1.549-2.902,2.021-3.872,2.504v-1.328c0-0.662,1.056-1.688,1.826-2.435
11
+ C8.502,11.961,9.498,11.193,9.498,10c0-1.193-0.996-1.961-2.051-2.986c-0.771-0.75-1.826-1.775-1.826-2.438L5.575,3.578
12
+ C6.601,4.131,8.227,4.656,10,4.656c1.772,0,3.406-0.525,4.433-1.078l-0.055,0.998c0,0.662-1.056,1.688-1.826,2.438
13
+ C11.498,8.039,10.501,8.807,10.501,10z"/>
14
+ </svg>
15
+
16
+ <p>Uploading your new header...</p>
17
+
18
+ <div class='progressbar'>
19
+ <span class='progress'></span>
20
+ </div>
21
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <%= form_for @post, as: :post, url: admin_posts_path, html: { class: %w(post new title), as: 'Posts.New' } do |f| %>
2
+
3
+ <%= content_tag :fieldset, class: %w(transparent) do |fieldset| %>
4
+ <% if @post.errors.any? %>
5
+ <% fieldset.css << 'errors' %>
6
+ <% end %>
7
+
8
+ <%= f.text_field :title, placeholder: t('admin.posts.new.title') %>
9
+ <% end %>
10
+
11
+ <% if @post.errors.any? %>
12
+ <ul class='errors'>
13
+ <% @post.errors.each do |key, message| %>
14
+ <%= content_tag :li, message %>
15
+ <% end %>
16
+ </ul>
17
+ <% else %>
18
+ <%= content_tag :p, t('admin.posts.new.editable'), class: %w(transparent) %>
19
+ <% end %>
20
+
21
+ <%= f.button :submit, class: %w(hidden) %>
22
+
23
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <%= content_tag :li, as: 'Post.Tag', oid: tag.id, href: admin_post_tag_path(@post, tag), method: :put do %>
2
+ <%= tag.name %>
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
5
+ <path d="M14.348,14.849c-0.469,0.469-1.229,0.469-1.697,0L10,11.819l-2.651,3.029c-0.469,0.469-1.229,0.469-1.697,0
6
+ c-0.469-0.469-0.469-1.229,0-1.697l2.758-3.15L5.651,6.849c-0.469-0.469-0.469-1.228,0-1.697c0.469-0.469,1.228-0.469,1.697,0
7
+ L10,8.183l2.651-3.031c0.469-0.469,1.228-0.469,1.697,0c0.469,0.469,0.469,1.229,0,1.697l-2.758,3.152l2.758,3.15
8
+ C14.817,13.62,14.817,14.38,14.348,14.849z"/>
9
+ </svg>
10
+ <% end %>
@@ -0,0 +1 @@
1
+ e.HTML = "<%= j render('admin/posts/tags/dialog/tag', tag: @tag, post: @post) %>".toHTML()
@@ -0,0 +1,3 @@
1
+ <%= content_tag :li, href: admin_post_tag_path(post, tag), method: :put, oid: tag.id do |li| %>
2
+ <%= tag.name %>
3
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <div class='overlay' as='Overlay'>
2
+ <div class='popup' as='Tags.List'>
3
+ <h2>Tags</h2>
4
+ <%= text_field_tag :tags, nil, placeholder: 'Create a new tag', href: admin_post_tags_path(@post) %>
5
+ <h3>Tags you haven't used for this post</h3>
6
+ <ul>
7
+ <% tags.each do |tag| %>
8
+ <%= render 'admin/posts/tags/dialog/tag', tag: tag, post: @post %>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ </div>
@@ -0,0 +1 @@
1
+ e.HTML = "<%= j render('admin/posts/tags/dialog/tags', tags: @tags) %>".toHTML()
@@ -0,0 +1,2 @@
1
+ e.ObjectID = <%= @tag.id %>
2
+ e.HTML = "<%= j render('admin/posts/tags/tag', post: @post, tag: @tag)%>".toHTML()
@@ -0,0 +1,11 @@
1
+ <div class='overlay' as='Overlay'>
2
+ <%= content_tag :div, class: %w(popup), as: 'Post.Title', href: admin_title_path(post.titles.last), method: 'PUT' do %>
3
+ <div class='progressbar'>
4
+ <span class='progress'></span>
5
+ </div>
6
+ <h3>Modify your title</h3>
7
+ <%= content_tag :div, post.title, contenteditable: true, class: %w(input) %>
8
+ <ul class='errors'></ul>
9
+ <p>Press Enter to update, or dismiss the popup to cancel.</p>
10
+ <% end %>
11
+ </div>
@@ -0,0 +1,22 @@
1
+ <div class='overlay' as='Overlay'>
2
+ <%= content_tag :div, class: %w(popup), as: 'Post.Title', href: admin_post_titles_path(post), method: 'POST' do %>
3
+ <div class='progressbar'>
4
+ <span class='progress'></span>
5
+ </div>
6
+ <h3>Create a new title</h3>
7
+ <%= content_tag :div, '', contenteditable: true, class: %w(input) %>
8
+ <ul class='errors'></ul>
9
+ <p>Press Enter to update, or dismiss the dialog to cancel.</p>
10
+ <p>For SEO & accessibility reason, you cannot edit previous post title for a published post. You can create a new title that will be the default one.</p>
11
+ <p><strong> All previous URL will redirect to the default newest URL.</strong></p>
12
+ <ul class='titles'>
13
+ <h4>Existing titles</h4>
14
+ <% post.titles.each do |title| %>
15
+ <%= content_tag :li do %>
16
+ <p class='title'><%= content_tag :strong, title.name %></p>
17
+ <%= content_tag :p, post_path(post, title: title, only_path: false), class: %w(url) %>
18
+ <% end %>
19
+ <% end %>
20
+ </ul>
21
+ <% end %>
22
+ </div>
@@ -0,0 +1 @@
1
+ e.Title = "<%= j @title.name %>"
@@ -0,0 +1 @@
1
+ e.HTML = "<%= j render('title', post: post) %>".toHTML()
@@ -0,0 +1,5 @@
1
+ e.Errors = [
2
+ <% @title.errors.each do |key, message| %>
3
+ "<%= j content_tag(:li, message) %>".toHTML(),
4
+ <% end %>
5
+ ]
@@ -0,0 +1 @@
1
+ e.HTML = "<%= j render('titles', post: post) %>".toHTML()
@@ -0,0 +1 @@
1
+ e.Title = "<%= j @title.name %>"
@@ -17,7 +17,7 @@
17
17
  </div>
18
18
  <div class='posts'>
19
19
  <h4>
20
- <%= link_to 'New post', new_title_admin_posts_path, class: %w(new button) %>
20
+ <%= link_to 'New post', new_admin_post_path, class: %w(new button) %>
21
21
  </h4>
22
22
  <%= link_to admin_posts_path(type: :draft), class: %w(drafts), remote: true, as: 'Posts.Popup' do %>
23
23
  <span class='type'>Drafts</span>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <section>
4
4
  <div class='posts'>
5
- <%= link_to 'New post', new_title_admin_posts_path, class: %w(new button) %>
5
+ <%= link_to 'New post', new_admin_post_path, class: %w(new button) %>
6
6
  <%= link_to admin_posts_path(type: :draft), class: %w(drafts), remote: true, as: 'Posts.Popup' do %>
7
7
  <span class='type'>Drafts</span>
8
8
  <%= content_tag :span, Post.drafted.count, class: %w(count) %>
@@ -2,7 +2,7 @@ require 'warden'
2
2
  require 'pg'
3
3
  require 's3'
4
4
  require 'kaminari'
5
- require 'jointjs'
5
+ require 'observejs'
6
6
 
7
7
  module Ecrire
8
8
  class Application < Rails::Application
@@ -14,9 +14,10 @@ Ecrire::Application.routes.draw do
14
14
  root 'posts#index'
15
15
  resources :posts do
16
16
  collection do
17
- get 'new/title', controller: :posts, action: :new
18
17
  get 'help', controller: :posts, action: :help
19
18
  end
19
+ resources :tags, only: [:index, :create, :update], module: 'posts'
20
+ resources :titles, shallow: true
20
21
  resource :image, shallow: true
21
22
  resource :properties, only: [:create, :destroy]
22
23
  end
@@ -29,4 +30,3 @@ Ecrire::Application.routes.draw do
29
30
  get '/:view', to: 'static#show'
30
31
 
31
32
  end
32
-
@@ -0,0 +1,27 @@
1
+ class MoveLabelsToTitles < ActiveRecord::Migration
2
+ class Title < ActiveRecord::Base
3
+ belongs_to :post
4
+ end
5
+
6
+ class Post < ActiveRecord::Base
7
+ end
8
+
9
+ def change
10
+ rename_table :labels, :titles
11
+
12
+ add_column :titles, :slug, :string, index: true
13
+ change_column :titles, :name, :string, unique: true, null: false
14
+ add_reference :titles, :post, index: true
15
+
16
+ Post.all.each do |post|
17
+ Title.create do |t|
18
+ t.slug = post.slug
19
+ t.name = post.title
20
+ t.post = post
21
+ end
22
+ end
23
+
24
+ remove_column :posts, :title
25
+ remove_column :posts, :slug
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ class CreateTags < ActiveRecord::Migration
2
+ def change
3
+ create_table :tags do |t|
4
+
5
+ t.string :name, null: false
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :tags, :name, unique: true
10
+
11
+ add_column :posts, :tags, :integer, array: true, defaut: []
12
+ end
13
+ end
@@ -11,46 +11,31 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20150120093481) do
14
+ ActiveRecord::Schema.define(version: 20150318549479) do
15
15
 
16
16
  # These are extensions that must be enabled in order to support this database
17
17
  enable_extension "plpgsql"
18
18
  enable_extension "hstore"
19
19
 
20
- create_table "abtests", force: :cascade do |t|
21
- t.datetime "created_at"
22
- t.datetime "updated_at"
23
- end
24
-
25
20
  create_table "images", force: :cascade do |t|
26
- t.string "url", limit: 255
27
- t.string "key", limit: 255
21
+ t.string "url"
22
+ t.string "key"
28
23
  t.integer "post_id"
29
24
  t.datetime "created_at"
30
25
  t.datetime "updated_at"
31
26
  t.boolean "favorite"
32
27
  end
33
28
 
34
- create_table "labels", force: :cascade do |t|
35
- t.string "name", limit: 255, null: false
36
- t.datetime "created_at"
37
- t.datetime "updated_at"
38
- end
39
-
40
- add_index "labels", ["name"], name: "index_labels_on_name", using: :btree
41
-
42
29
  create_table "partials", force: :cascade do |t|
43
30
  t.datetime "created_at"
44
31
  t.datetime "updated_at"
45
- t.string "title", limit: 255, null: false
32
+ t.string "title", null: false
46
33
  t.text "content"
47
34
  t.text "stylesheet"
48
35
  t.text "javascript"
49
36
  end
50
37
 
51
38
  create_table "posts", force: :cascade do |t|
52
- t.string "title", limit: 255, null: false
53
- t.string "slug", limit: 255, null: false
54
39
  t.text "content"
55
40
  t.text "stylesheet"
56
41
  t.datetime "published_at"
@@ -60,13 +45,31 @@ ActiveRecord::Schema.define(version: 20150120093481) do
60
45
  t.hstore "properties"
61
46
  t.text "compiled_content"
62
47
  t.text "compiled_excerpt"
48
+ t.integer "tags", array: true
49
+ end
50
+
51
+ create_table "tags", force: :cascade do |t|
52
+ t.string "name", null: false
53
+ t.datetime "created_at"
54
+ t.datetime "updated_at"
55
+ end
56
+
57
+ add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
58
+
59
+ create_table "titles", force: :cascade do |t|
60
+ t.string "name", null: false
61
+ t.datetime "created_at"
62
+ t.datetime "updated_at"
63
+ t.string "slug"
64
+ t.integer "post_id"
63
65
  end
64
66
 
65
- add_index "posts", ["title"], name: "index_posts_on_title", unique: true, using: :btree
67
+ add_index "titles", ["name"], name: "index_titles_on_name", using: :btree
68
+ add_index "titles", ["post_id"], name: "index_titles_on_post_id", using: :btree
66
69
 
67
70
  create_table "users", force: :cascade do |t|
68
- t.string "email", limit: 255, null: false
69
- t.string "encrypted_password", limit: 255, null: false
71
+ t.string "email", null: false
72
+ t.string "encrypted_password", null: false
70
73
  t.datetime "created_at"
71
74
  t.datetime "updated_at"
72
75
  end
@@ -1,2 +1,2 @@
1
- //= require joint
1
+ //= require observejs
2
2
  //= require_tree .
@@ -1,4 +1,4 @@
1
- Joint.bind 'Database.Information', class
1
+ ObserveJS.bind 'Database.Information', class
2
2
  loaded: =>
3
3
  @on 'input', @element().querySelector('form'), @update
4
4
 
@@ -1,4 +1,4 @@
1
- Joint.bind 'Message', class
1
+ ObserveJS.bind 'Message', class
2
2
  loaded: =>
3
3
 
4
4
  remove: =>
@@ -1,10 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'ecrire', git: 'https://github.com/pothibo/ecrire'
3
+ gem 'ecrire', path: '~/Develop/ecrire'
4
4
 
5
5
  group :required do
6
6
  gem 'rails', '~> 4.2'
7
- gem 'jointjs', '~> 0.0'
7
+ gem 'observejs', '~> 0.0'
8
8
  gem 'warden', '~> 1.2'
9
9
  gem 'bcrypt', '~> 3.1'
10
10
  gem 'nokogiri', '~> 1.6'
@@ -18,7 +18,8 @@ group :required do
18
18
  gem 'coffee-rails', '~> 4.0'
19
19
  gem 'turbolinks', '~> 2.2'
20
20
  gem 'bourbon', '~> 3.2'
21
- gem 'uglifier', '~> 2.5'
21
+ gem 'uglifier', '~> 2.5'
22
+ gem 'jbuilder' '~> 2.2'
22
23
  end
23
24
 
24
25
  group :server do
@@ -0,0 +1 @@
1
+ #= require_tree .
@@ -1,3 +1,3 @@
1
1
  module Ecrire
2
- VERSION = '0.22.1'
2
+ VERSION = '0.23.0'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'editor/test_helper'
2
+ require 'byebug'
2
3
 
3
4
  class BaseControllerTest < ActionController::TestCase
4
5
  include Warden::Test::Helpers
@@ -1,6 +1,26 @@
1
1
  require 'editor/test_helper'
2
2
 
3
3
  class PostTest < ActiveSupport::TestCase
4
+
5
+ test 'creation will bind a new title to this post' do
6
+ post = Post.new
7
+ post.title = "test"
8
+ assert post.save, post.errors.full_messages.to_sentence
9
+ assert post.titles.count == 1
10
+ post.titles.each do |title|
11
+ assert title.persisted?
12
+ end
13
+ end
14
+
15
+ test 'post can have tags' do
16
+ tag = tags(:ruby)
17
+ post = posts(:published)
18
+ post.tags << tag
19
+ assert post.save, post.errors.full_messages.to_sentence
20
+ assert post.tags.include?(tag)
21
+ assert post.read_attribute(:tags).include?(tag.id)
22
+ end
23
+
4
24
  test "fetch published post" do
5
25
  @posts = Post.status("published")
6
26
  assert_equal @posts.count, Post.published.count
@@ -26,7 +46,7 @@ class PostTest < ActiveSupport::TestCase
26
46
 
27
47
  test "publishing a post" do
28
48
  @post = Post.new
29
- @post.title = "Some new post"
49
+ @post.titles << Title.new(name: "Some new post", post: @post)
30
50
  assert @post.draft?, "Should be a draft"
31
51
  @post.publish!
32
52
  assert @post.published?, "Should be published"
@@ -39,28 +59,16 @@ class PostTest < ActiveSupport::TestCase
39
59
  assert_equal published_at, @post.published_at, "Shouldn't be able to change the published date"
40
60
  end
41
61
 
42
- test "should create a slug if none exist" do
43
- @post = Post.new
44
- @post.title = "some test"
45
- !@post.save
46
- assert !@post.slug.nil?
47
- end
48
-
49
- test "can't save a post if the title already exists" do
50
- @old_post = Post.first
51
- @post = Post.new
52
- @post.title = @old_post.title
53
- assert !@post.save, "The post shouldn't save."
54
- assert @post.errors.has_key?(:title), 'There should be an error with the title'
55
- end
56
-
57
62
  test "exerpt does not include images" do
58
- post = Admin::Post.create!({
59
- title: "A new post",
63
+ post = Admin::Post.new({
60
64
  content: "Hello
61
65
  ![a](http://google.com)"
62
66
  })
63
67
 
68
+ post.titles << Admin::Title.new(name: "Post Image test.", post: post)
69
+
70
+ assert post.save, post.errors.full_messages.to_sentence
71
+
64
72
  html = Nokogiri::HTML(post.compiled_excerpt)
65
73
 
66
74
  assert html.css('p').length > 0
@@ -68,42 +76,4 @@ class PostTest < ActiveSupport::TestCase
68
76
 
69
77
  end
70
78
 
71
- test "can't save a post if the slug already exists" do
72
- @old_post = Post.first
73
- @post = Post.new
74
- @post.slug = @old_post.slug
75
- assert !@post.save, "The post shouldn't save."
76
- assert @post.errors.has_key?(:slug), 'There should be an error with the slug'
77
- end
78
-
79
- test 'should be able to add labels' do
80
- @post = posts(:draft)
81
- label = Label.create(name: 'A label')
82
- @post.labels = [label]
83
- assert @post.save
84
- end
85
-
86
- test 'labels are arrays of Label' do
87
- @post = posts(:draft)
88
- label = Label.create(name: 'A label')
89
- @post.labels = [label]
90
- assert @post.save
91
- assert_equal @post.labels.first, label
92
- assert_kind_of Array, @post.labels
93
- assert_kind_of Label, @post.labels.first
94
- end
95
-
96
- test 'labels are instance of Label' do
97
- end
98
-
99
- test 'only 1 image can be associated with a post' do
100
- post = Admin::Post.create!(title: 'A post with some image')
101
- assert_equal 1, Image.where('post_id = ?', post.id).count
102
-
103
- post.content = '# Hello world'
104
- post.save!
105
-
106
- assert_equal 1, Image.where('post_id = ?', post.id).count
107
- end
108
-
109
79
  end