ecrire 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33bd25681de527f9d535b8d9f224ee339cc7538b
4
- data.tar.gz: 698be69f0e07e6562f8f2640e92a19d00abeb61c
3
+ metadata.gz: b9187d5d3cf47bd6d98975d2c7e98f78fca7e724
4
+ data.tar.gz: bb54f17491247dfe317ca7ba9ef3fe78089936c7
5
5
  SHA512:
6
- metadata.gz: c59825dc64583000eb193136d440b80133576ee22975ce33e350aaa1e62f15044ab6b3efa91520ec9d9c7f68c4123485188a67542f91416d1ec6d159c391a037
7
- data.tar.gz: 72e412b0db648761f63f2e63e13621bbd508788c722ccb9ef2ca48fbd99f0ae5e08b17dc6bb3a7bab4d43090d275f986d1890d3a12bb5c5b3509ea16291a97f0
6
+ metadata.gz: d7887948635cf02da8caaed5c802c34e2f8ca0baa3e6d53f8cf04caccec39444a542a67a45a9b2026b739b9ca5ff290544f0908e9b3fefb96b4724e2ab8c9d60
7
+ data.tar.gz: b12bfee9bd7bde93f8d37b514df86f01add1c972884998af6fa05a930aae3e610eee4b1f9000fe1c5ac281940dc0b42fa9f40bc288498c617c2741965e1375d5
data/README.md CHANGED
@@ -1,62 +1,64 @@
1
1
  # Ecrire
2
2
 
3
- ![The Editor](http://f.cl.ly/items/1u0r3g0E1r3x2z1g2G1P/Screen%20Shot%202014-06-16%20at%206.19.06%20PM.png)
3
+ Ecrire is a blog built *on top* of Ruby on Rails. The goal of this blog engine is to make it **easy** to start a blog while keeping control over the content. You can see this as an alternative to WordPress.
4
4
 
5
- Starting your own blog isn't an easy task. If you've ever started one, you know how hard it is to stay focused. With ecrire, you have all the tools you need to help you get started.
5
+ ## The editor
6
+ The editor was built around the Markdown syntax. The content change as you type to offer you a very good approximation of how your post will look like once publish.
6
7
 
7
- The interface is light and the editor is at the forefront. Because writing, that's what we do.
8
+ Here's the available feature:
9
+ - Headers
10
+ - Unordered list
11
+ - Ordered list
12
+ - Code with syntax highlighting
13
+ - Image with auto-upload to S3
14
+ - Links
15
+ - Bold and Italic words
8
16
 
9
- And it doesn't stop there. You have the ability to change personalize each and every post like you would for a web page. You can customize your page with custom Javascript and CSS. And to make your life even easier, those two are evaluated in **real time**.
17
+ More feature will be implemented as the Editor mature.
10
18
 
11
- Don't worry about saving your drafts, Ecrire does it for you every half a second. We're in 2014, after all.
19
+ ## Theme
20
+ When you start a new blog with Ecrire, it will generate a folder for you. Everything in that folder is for you to modify. You won't break anything. It also features a few characteristic that you may recognize if you are a Rails developer.
12
21
 
13
- Ecrire is built on top of Ruby on Rails, that means that every theme you build can be built with ruby helpers and decorators while having the power to write clean HTML. Your views can be neatly organized and clean.
22
+ - SASS
23
+ - Coffeescript
24
+ - Assets caching through Sprockets
25
+ - View using layouts, views and partials
26
+ - Controllers
27
+ - Helpers
28
+ - Static pages
14
29
 
15
- Same goes for your CSS and Javascript files. Ecrire comes with SASS & Bourbon for the CSS interpreter. Coffeescript is also available for your javascript.
30
+ When you install your theme, the documentation will be available direclty within your blog so you can go back to it when you need it.
16
31
 
17
- Go ahead, try it out!
32
+ ## How to install
18
33
 
34
+ ```bash
35
+ $ gem install ecrire
36
+ $ ecrire new my.blog.com
37
+ $ cd my.blog.com/
38
+ $ ecrire server
39
+ ```
19
40
 
20
- ### Getting started
41
+ From there, you can access your new blog via the browser and start configuring your database.
21
42
 
22
- First, you need to have ruby version **higher than** 2.0.0.
43
+ ## Heroku
23
44
 
24
- You can install the gem with rubygems.
25
- ``` gem install ecrire ```
45
+ Once you have finished your changes in your local environment, here's how you can publish your blog on Heroku.
26
46
 
27
- Then create a new blog
28
- ``` ecrire new your_blog_name ```
47
+ ~~~bash
48
+ $ heroku git:remote -a name-of-your-app-on-heroku
49
+ $ git push origin heroku
50
+ $ heroku run rake db:migrate
51
+ ~~~
29
52
 
30
- It will create a new blog using the default template. Before starting up your server, you will need to run Bundler to install all the dependency your blog needs.
31
- ``` bundle install ```
53
+ Your blog is now up and running on Heroku! But you need to create a user on Heroku for now, here's how you do it.
32
54
 
33
- You are ready to go. Ecrire will launch the onboarding process until you set up your database and you create a user.
55
+ ~~~ruby
56
+ $ heroku run ecrire console
57
+ irb(main)> user = User.new
58
+ irb(main)> user.email = "your@email.com"
59
+ irb(main)> user.password = "yourpassword"
60
+ irb(main)> user.save!
61
+ irb(main)> exit
62
+ ~~~
34
63
 
35
- ``` bundle exec ecrire server  ```
36
-
37
- You can access the blog & configuration setup with your browser by going at the following address.
38
- ``` http://localhost:3000  ```
39
-
40
- ### Licence
41
-
42
- The MIT License (MIT)
43
-
44
- Copyright (c) 2014 pothibo
45
-
46
- Permission is hereby granted, free of charge, to any person obtaining a copy
47
- of this software and associated documentation files (the "Software"), to deal
48
- in the Software without restriction, including without limitation the rights
49
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50
- copies of the Software, and to permit persons to whom the Software is
51
- furnished to do so, subject to the following conditions:
52
-
53
- The above copyright notice and this permission notice shall be included in
54
- all copies or substantial portions of the Software.
55
-
56
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
60
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62
- THE SOFTWARE.
64
+ You can now log in to your blog in production and start writing for real!
@@ -59,21 +59,23 @@ Joint.bind 'Editor.Content', class @Editor
59
59
 
60
60
  sel = window.getSelection()
61
61
  node = focusNode = sel.focusNode
62
- offset = sel.focusOffset
63
-
64
- str = focusNode.textContent
65
- focusNode.textContent = str.substr(0, offset) + "\n" + str.substr(offset)
66
62
 
67
63
  while node? && node.parentElement != @element()
68
64
  node = node.parentElement
69
-
70
- offset = @lineOffset(node, focusNode, offset) + 1
71
65
 
72
- lines = @parse(@cloneNodesFrom(node))
66
+ offset = @lineOffset(node, focusNode, sel.focusOffset)
67
+
68
+ lineFeed = new LineFeed(@cloneNodesFrom(node))
69
+ lineFeed.injectAt(offset)
70
+
71
+ cursor = new Editor.Cursor(offset + 1)
72
+
73
+ lines = @parse(lineFeed.fragment)
73
74
 
74
75
  @observer.hold =>
75
- lines = @updateDOM(node, lines)
76
- @setCursorAt(lines[0], offset)
76
+ line = cursor.focus(@updateDOM(node, lines)[0])
77
+ cursor.update(@walker(line))
78
+ @scrollLineIntoView(cursor.focus())
77
79
 
78
80
 
79
81
  event = new CustomEvent('Editor:updated', {bubbles: true})
@@ -97,13 +99,12 @@ Joint.bind 'Editor.Content', class @Editor
97
99
  offset += node.toString().length + 1
98
100
 
99
101
  lines = @parse(@cloneNodesFrom(node))
102
+ cursor = new Editor.Cursor(offset)
100
103
 
101
104
  @observer.hold =>
102
- lines = @updateDOM(node, lines)
103
- for line in lines
104
- if line.parentElement?
105
- @setCursorAt(lines[0], offset)
106
- break
105
+ line = cursor.focus(@updateDOM(node, lines)[0])
106
+ cursor.update(@walker(line))
107
+ @scrollLineIntoView(cursor.focus())
107
108
 
108
109
 
109
110
  removed: (node, line) =>
@@ -116,18 +117,19 @@ Joint.bind 'Editor.Content', class @Editor
116
117
  if line?
117
118
  sel = window.getSelection()
118
119
  offset = @lineOffset(line, sel.focusNode, sel.focusOffset)
120
+ cursor = new Editor.Cursor(offset)
119
121
 
120
122
  lines = @parse(@cloneNodesFrom(line))
121
123
 
122
124
  @observer.hold =>
123
- lines = @updateDOM(line, lines)
124
- if line != lines[0]
125
- @setCursorAt(lines[0], offset)
125
+ line = cursor.focus(@updateDOM(line, lines)[0])
126
+ cursor.update(@walker(line))
126
127
 
127
128
  if @element().childNodes.length == 0
128
129
  p = "<p>".toHTML()
129
130
  @element().appendChild(p)
130
- @setCursorAt(@element(), 0)
131
+ cursor = new Editor.Cursor(offset)
132
+ cursor.update(@walker(p), 0)
131
133
 
132
134
 
133
135
 
@@ -152,16 +154,25 @@ Joint.bind 'Editor.Content', class @Editor
152
154
 
153
155
  sel = window.getSelection()
154
156
  offset = @lineOffset(el, sel.focusNode, sel.focusOffset)
157
+ cursor = new Editor.Cursor(offset)
155
158
 
156
159
  lines = @parse(@cloneNodesFrom(node))
157
160
 
158
161
  @observer.hold =>
159
162
  lines = @updateDOM(node, lines)
160
163
  if node != lines[0]
161
- @setCursorAt(lines[0], offset)
164
+ cursor.update(@walker(lines[0]))
165
+ @scrollLineIntoView(lines[0])
162
166
 
163
167
 
164
168
 
169
+ scrollLineIntoView: (line) =>
170
+ height = window.innerHeight
171
+ rect = line.getBoundingClientRect()
172
+
173
+ if rect.bottom > height
174
+ line.scrollIntoView()
175
+
165
176
  updateDOM: (anchor, fragment) =>
166
177
  return unless anchor?
167
178
  current = anchor.parentElement.lastChild
@@ -213,6 +224,10 @@ Joint.bind 'Editor.Content', class @Editor
213
224
 
214
225
 
215
226
  lineOffset: (line, node, offset) =>
227
+
228
+ if node.nodeType == document.ELEMENT_NODE
229
+ return node.textContent.length
230
+
216
231
  if node.textContent.length == 0
217
232
  return 0
218
233
 
@@ -221,34 +236,6 @@ Joint.bind 'Editor.Content', class @Editor
221
236
 
222
237
 
223
238
 
224
- setCursorAt: (line, offset) ->
225
- sel = window.getSelection()
226
-
227
- while true
228
- length = line.toString().length
229
- if length >= offset
230
- break
231
- offset -= Math.max(length + 1, 1)
232
-
233
- if line.nextSibling?
234
- line = line.nextSibling
235
- continue
236
- break
237
-
238
- walker = @walker(line)
239
- range = line.getRange(offset , walker)
240
-
241
- height = window.innerHeight
242
- rect = line.getBoundingClientRect()
243
-
244
- if rect.bottom > height
245
- line.scrollIntoView()
246
-
247
- sel.removeAllRanges()
248
- sel.addRange(range)
249
-
250
-
251
-
252
239
  cloneNodesFrom: (node) =>
253
240
  fragment = document.createDocumentFragment()
254
241
  while node
@@ -313,7 +300,75 @@ Joint.bind 'Editor.Content', class @Editor
313
300
 
314
301
  texts.join '\n'
315
302
 
303
+ class @Editor.Cursor
304
+ constructor: (offset) ->
305
+ @selection = window.getSelection()
306
+ @origin = @selection.focusNode
307
+
308
+ @offset = offset
309
+
310
+ focus: (line) ->
311
+ while true
312
+ length = line.toString().length
313
+ if length >= @offset
314
+ break
315
+ @offset -= Math.max(length + 1, 1)
316
+
317
+ if line.nextSibling?
318
+ line = line.nextSibling
319
+ continue
320
+ break
321
+
322
+ @focus = ->
323
+ line
324
+
325
+ @focus()
326
+
327
+ update: (walker, force = false) ->
328
+ line = walker.root
329
+
330
+ if !force && @selection.focusNode == @origin && line.contains(@origin)
331
+ return
332
+
333
+ range = line.getRange(@offset, walker)
334
+
335
+ @selection.removeAllRanges()
336
+ @selection.addRange(range)
337
+
338
+ class LineFeed
339
+ constructor: (@fragment) ->
340
+
341
+ injectAt: (offset) ->
342
+ node = @fragment.firstChild
343
+ while node && offset > 0
344
+ length = node.textContent.length
345
+ if offset > length
346
+ offset -= length + 1
347
+ node = node.nextSibling
348
+ else
349
+ break
350
+
351
+ if !node?
352
+ @append(@fragment.lastChild)
353
+ else
354
+ @insert(node, offset)
355
+
356
+ append: (lastChild) ->
357
+ node = lastChild.cloneNode(true)
358
+ node.textContent = ''
359
+ @fragment.appendChild(node)
360
+
361
+ insert: (root, offset) ->
362
+ node = root.cloneNode(true)
363
+
364
+ root.textContent = root.textContent.substr(0, offset)
365
+ node.textContent = node.textContent.substr(offset)
366
+
367
+ if root.nextSibling?
368
+ @fragment.insertBefore(node, root.nextSibling)
369
+ else
370
+ @fragment.appendChild(node)
371
+
316
372
 
317
373
  Editor.Parsers = []
318
374
  Editor.Extensions = []
319
-
@@ -14,10 +14,16 @@ HTMLOListElement::toString = HTMLUListElement::toString = ->
14
14
  li.textContent
15
15
  texts.join("\n")
16
16
 
17
- HTMLPictureElement::toString = ->
18
- @lastChild.textContent
17
+ HTMLDivElement::toString = ->
18
+ if @classList.contains('image')
19
+ @lastChild.textContent
20
+ else
21
+ @textContent
22
+
23
+ HTMLPreElement::toString = ->
24
+ @textContent
19
25
 
20
- HTMLPreElement::toString = HTMLHeadingElement::toString = HTMLDivElement::toString = HTMLParagraphElement::toString = ->
26
+ HTMLHeadingElement::toString = HTMLParagraphElement::toString = ->
21
27
  @textContent
22
28
 
23
29
  HTMLElement::offset = (node, walker) ->
@@ -42,7 +42,7 @@ Editor.Extensions.push class ClipBoard
42
42
 
43
43
 
44
44
  replace: (texts, sel) =>
45
-
45
+
46
46
  node = sel.extentNode
47
47
  line = node
48
48
  nodes = [node]
@@ -62,14 +62,15 @@ Editor.Extensions.push class ClipBoard
62
62
  t.textContent
63
63
  ).join()
64
64
 
65
-
65
+
66
66
  line.textContent = line.textContent.substr(0, offsets.start) + text + line.textContent.substr(offsets.end)
67
67
 
68
68
  fragment = @editor.parse(@editor.cloneNodesFrom(line))
69
69
 
70
70
  @editor.updateDOM(line, fragment)
71
71
 
72
- @editor.setCursorAt(line, offsets.start + text.length)
72
+ cursor = new Editor.Cursor(offsets.start + text.length)
73
+ cursor.update(@editor.walker(cursor.focus(line)), true)
73
74
 
74
75
 
75
76
  insert: (texts, sel) =>
@@ -84,15 +85,30 @@ Editor.Extensions.push class ClipBoard
84
85
  node.textContent += text
85
86
  node.textContent += str.substr(sel.anchorOffset)
86
87
 
87
- offset = sel.anchorOffset + text.length
88
-
89
- while node.parentElement != @editor.element()
90
- node = node.parentElement
88
+ line = node
89
+ while line.parentElement != @editor.element()
90
+ line = line.parentElement
91
+
92
+ offset = @nodeOffset(node,line) + sel.anchorOffset + text.length
93
+
94
+ fragment = @editor.parse(@editor.cloneNodesFrom(line))
91
95
 
92
- fragment = @editor.parse(@editor.cloneNodesFrom(node))
96
+ lines = @editor.updateDOM(line, fragment)
93
97
 
94
- lines = @editor.updateDOM(node, fragment)
98
+ cursor = new Editor.Cursor(offset)
99
+ cursor.update(@editor.walker(cursor.focus(lines[0])), true)
95
100
 
96
- @editor.setCursorAt(lines[0], offset)
101
+ nodeOffset: (node, line) ->
102
+ if !line.contains(node)
103
+ raise "Looking for a node that is not inside the given line"
104
+ return
97
105
 
106
+ offset = 0
107
+
108
+ for n in line.childNodes
109
+ if n == node
110
+ break
111
+ else
112
+ offset += n.textContent.length
98
113
 
114
+ offset
@@ -0,0 +1,10 @@
1
+ Joint.bind 'Editor.Code', class
2
+ loaded: =>
3
+ document.addEventListener 'keydown', @filter, true
4
+
5
+ filter: (e) =>
6
+ switch e.which
7
+ when 13 then @linefeed(e)
8
+
9
+ linefeed: (e) =>
10
+
@@ -9,7 +9,7 @@ Joint.bind 'Editor.Save', class
9
9
  @on 'click', @button, @save
10
10
  @on 'beforeunload', window, @confirm
11
11
 
12
- @button.innerText = @button.getAttribute('persisted')
12
+ @button.textContent = @button.getAttribute('persisted')
13
13
  @refresh()
14
14
  @cache()
15
15
  @interval = setInterval(@refresh, 1000)
@@ -28,7 +28,7 @@ Joint.bind 'Editor.Save', class
28
28
  if refresh
29
29
  cache = PostBody.instance.toString()
30
30
  @button.setAttribute('disabled', 'disabled')
31
- @button.innerText = @button.getAttribute('persisted')
31
+ @button.textContent = @button.getAttribute('persisted')
32
32
  cache
33
33
  @cache()
34
34
 
@@ -42,10 +42,7 @@ Joint.bind 'Editor.Save', class
42
42
  xhr.send()
43
43
 
44
44
  saved: (e) =>
45
- if e.MessageHTML
46
- event = new CustomEvent('Editor:message', { bubbles: true})
47
- event.MessageHTML = e.MessageHTML
48
- @element().dispatchEvent(event)
45
+ if e.UpdatedAtTime
49
46
  @time.setAttribute('time', e.UpdatedAtTime)
50
47
  @refresh()
51
48
  @cache(true)
@@ -54,8 +51,8 @@ Joint.bind 'Editor.Save', class
54
51
  return unless @cache()?
55
52
  if @cache() != PostBody.instance.toString()
56
53
  @button.removeAttribute('disabled')
57
- @button.innerText = @button.getAttribute('dirty')
54
+ @button.textContent = @button.getAttribute('dirty')
58
55
  else
59
56
  @button.setAttribute('disabled', 'disabled')
60
- @button.innerText = @button.getAttribute('persisted')
57
+ @button.textContent = @button.getAttribute('persisted')
61
58
 
@@ -1,5 +1,5 @@
1
1
  Editor.Parsers.push class
2
- rule: /^((~{3,})([a-z]+)?$)(.+)?(~{3,}$)?/mi
2
+ rule: /^((~{3,})([a-z]+)?)(.+)?(~{3,}$)?/mi
3
3
 
4
4
  constructor: (node) ->
5
5
  @nodes = [node]
@@ -28,11 +28,15 @@ Editor.Parsers.push class
28
28
 
29
29
  render: =>
30
30
  pre = "<pre>".toHTML()
31
- code = "<code>".toHTML()
31
+ code = "<code as='Editor.Code'>".toHTML()
32
+
32
33
  if @match[3]?
33
34
  code.classList.add("language-#{@match[3]}")
35
+
34
36
  texts = @nodes.map (n) -> n.textContent
35
- code.textContent = texts.join("\n")
37
+
38
+ code.textContent = texts.join('\n')
39
+
36
40
  Prism.highlightElement(code)
37
41
  pre.appendChild(code)
38
42
  pre
@@ -14,7 +14,7 @@ Editor.Parsers.push class
14
14
  @uploader = new Editor.ImageUploader(@show)
15
15
 
16
16
 
17
- @picture = "<picture as='Editor.Image'>".toHTML()
17
+ @picture = "<div class='image' as='Editor.Image'>".toHTML()
18
18
 
19
19
  @title = "<em></em>".toHTML()
20
20
  @title.appendChild document.createTextNode(@match[1])
@@ -3,6 +3,31 @@ body.edit.posts > main > section {
3
3
  @include flex(1);
4
4
  outline: none;
5
5
  font-size: 1.2em;
6
+ padding-bottom: 10em;
7
+
8
+ h1 {
9
+ font-size: 2.6em;
10
+ }
11
+
12
+ h2 {
13
+ font-size: 2.3em;
14
+ }
15
+
16
+ h3 {
17
+ font-size: 2.0em;
18
+ }
19
+
20
+ h4 {
21
+ font-size: 1.7em;
22
+ }
23
+
24
+ h5 {
25
+ font-size: 1.6em;
26
+ }
27
+
28
+ h6 {
29
+ font-size: 1.3em;
30
+ }
6
31
 
7
32
  & > *, & > ul > li, & > ol > li {
8
33
  white-space: pre-wrap;
@@ -15,7 +40,11 @@ body.edit.posts > main > section {
15
40
  margin-left: 2em;
16
41
  }
17
42
 
18
- & > picture {
43
+ & > pre {
44
+ background: rgba(0,0,0, 0.1);
45
+ }
46
+
47
+ & > div.image {
19
48
  @include display(flex);
20
49
  @include flex-direction(column);
21
50
  @include transition(background-color 0.3s);
@@ -26,6 +26,11 @@ div.popup {
26
26
  box-shadow: 0 0 3px #1a3642;
27
27
  color: #15191B;
28
28
  z-index: 101;
29
+
30
+ h1, h2, h3, h4, h5, h6 {
31
+ font-family: initial;
32
+ font-weight: bold;
33
+ }
29
34
  }
30
35
 
31
36
  div.popup header {
@@ -27,7 +27,7 @@ module Ecrire
27
27
  protected
28
28
 
29
29
  def posts
30
- @post ||= Post.published.page(params[:page]).per(params[:per]).order(:published_at)
30
+ @posts ||= Post.published.page(params[:page]).per(params[:per]).order('published_at DESC')
31
31
  end
32
32
 
33
33
  def post
@@ -23,7 +23,7 @@
23
23
 
24
24
  <section class='code'>
25
25
  <h3>Code block</h3>
26
- <pre><code>~~~ language
26
+ <pre><code>~~~language
27
27
  [1,2,3].each do |i|
28
28
  puts i
29
29
  end
@@ -17,14 +17,9 @@ ActiveRecord::Schema.define(version: 20150120093481) do
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"
@@ -32,7 +27,7 @@ ActiveRecord::Schema.define(version: 20150120093481) do
32
27
  end
33
28
 
34
29
  create_table "labels", force: :cascade do |t|
35
- t.string "name", limit: 255, null: false
30
+ t.string "name", null: false
36
31
  t.datetime "created_at"
37
32
  t.datetime "updated_at"
38
33
  end
@@ -42,15 +37,15 @@ ActiveRecord::Schema.define(version: 20150120093481) do
42
37
  create_table "partials", force: :cascade do |t|
43
38
  t.datetime "created_at"
44
39
  t.datetime "updated_at"
45
- t.string "title", limit: 255, null: false
40
+ t.string "title", null: false
46
41
  t.text "content"
47
42
  t.text "stylesheet"
48
43
  t.text "javascript"
49
44
  end
50
45
 
51
46
  create_table "posts", force: :cascade do |t|
52
- t.string "title", limit: 255, null: false
53
- t.string "slug", limit: 255, null: false
47
+ t.string "title", null: false
48
+ t.string "slug", null: false
54
49
  t.text "content"
55
50
  t.text "stylesheet"
56
51
  t.datetime "published_at"
@@ -65,8 +60,8 @@ ActiveRecord::Schema.define(version: 20150120093481) do
65
60
  add_index "posts", ["title"], name: "index_posts_on_title", unique: true, using: :btree
66
61
 
67
62
  create_table "users", force: :cascade do |t|
68
- t.string "email", limit: 255, null: false
69
- t.string "encrypted_password", limit: 255, null: false
63
+ t.string "email", null: false
64
+ t.string "encrypted_password", null: false
70
65
  t.datetime "created_at"
71
66
  t.datetime "updated_at"
72
67
  end
@@ -8,7 +8,7 @@ module Sprockets
8
8
  module Rails
9
9
  class Task < Rake::SprocketsTask
10
10
  def output
11
- File.join(Ecrire::Railtie.paths['public'].existent.first, app.config.assets.prefix)
11
+ File.join(Ecrire::Railtie.paths['public'].expanded.first, app.config.assets.prefix)
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,6 @@
1
+ namespace :db do
2
+ task :environment do
3
+ Ecrire::Application.initialize!
4
+ end
5
+
6
+ end
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'ecrire', '~> 0.1'
3
+ gem 'ecrire', path: '~/Develop/ecrire'
4
4
 
5
5
  group :required do
6
6
  gem 'rails', '~> 4.2'
@@ -0,0 +1,2 @@
1
+ web: bundle exec rackup config.ru -p $PORT
2
+
@@ -1,3 +1,3 @@
1
1
  module Ecrire
2
- VERSION = '0.20.0'
2
+ VERSION = '0.21.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecrire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pier-Olivier Thibault
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-18 00:00:00.000000000 Z
11
+ date: 2015-02-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Blog engine on Rails
14
14
  email: pothibo@gmail.com
@@ -29,6 +29,7 @@ files:
29
29
  - lib/ecrire/app/assets/javascripts/admin/editor/content.coffee
30
30
  - lib/ecrire/app/assets/javascripts/admin/editor/ext.coffee
31
31
  - lib/ecrire/app/assets/javascripts/admin/editor/extensions/clipboard.coffee
32
+ - lib/ecrire/app/assets/javascripts/admin/editor/extensions/code.coffee
32
33
  - lib/ecrire/app/assets/javascripts/admin/editor/extensions/image.coffee
33
34
  - lib/ecrire/app/assets/javascripts/admin/editor/navigation/delete.js.coffee
34
35
  - lib/ecrire/app/assets/javascripts/admin/editor/navigation/draft.js.coffee
@@ -192,8 +193,10 @@ files:
192
193
  - lib/ecrire/railtie/onboarding.rb
193
194
  - lib/ecrire/railtie/theme.rb
194
195
  - lib/ecrire/tasks/assets.rake
196
+ - lib/ecrire/tasks/database.rake
195
197
  - lib/ecrire/tasks/routes.rake
196
198
  - lib/ecrire/template/Gemfile
199
+ - lib/ecrire/template/Procfile
197
200
  - lib/ecrire/template/Rakefile
198
201
  - lib/ecrire/template/assets/images/.keep
199
202
  - lib/ecrire/template/assets/javascripts/base.js.coffee
@@ -268,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
271
  version: '0'
269
272
  requirements: []
270
273
  rubyforge_project:
271
- rubygems_version: 2.0.14
274
+ rubygems_version: 2.2.2
272
275
  signing_key:
273
276
  specification_version: 4
274
277
  summary: Blog engine