sir_trevor_rails 0.5.0b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/CHANGELOG +13 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +126 -0
  7. data/Rakefile +7 -0
  8. data/app/views/sir_trevor/_sir_trevor_block_array.html.erb +1 -0
  9. data/app/views/sir_trevor/blocks/_heading_block.html.erb +1 -0
  10. data/app/views/sir_trevor/blocks/_image_block.html.erb +5 -0
  11. data/app/views/sir_trevor/blocks/_list_block.html.erb +3 -0
  12. data/app/views/sir_trevor/blocks/_quote_block.html.erb +13 -0
  13. data/app/views/sir_trevor/blocks/_text_block.html.erb +3 -0
  14. data/app/views/sir_trevor/blocks/_tweet_block.html.erb +9 -0
  15. data/app/views/sir_trevor/blocks/videos/_vimeo.html.erb +4 -0
  16. data/app/views/sir_trevor/blocks/videos/_youtube.html.erb +4 -0
  17. data/config/initializers/validators.rb +12 -0
  18. data/config.ru +7 -0
  19. data/lib/generators/sir_trevor_rails/block/block_generator.rb +33 -0
  20. data/lib/generators/sir_trevor_rails/block/templates/_block.html.erb +3 -0
  21. data/lib/generators/sir_trevor_rails/block/templates/_block.js +203 -0
  22. data/lib/generators/sir_trevor_rails/block/templates/_block.rb +2 -0
  23. data/lib/generators/sir_trevor_rails/views/views_generator.rb +17 -0
  24. data/lib/sir_trevor_rails/block.rb +63 -0
  25. data/lib/sir_trevor_rails/block_array.rb +21 -0
  26. data/lib/sir_trevor_rails/blocks/tweet_block.rb +35 -0
  27. data/lib/sir_trevor_rails/blocks/video_block.rb +9 -0
  28. data/lib/sir_trevor_rails/engine.rb +34 -0
  29. data/lib/sir_trevor_rails/has_sir_trevor_content.rb +27 -0
  30. data/lib/sir_trevor_rails/helpers/view_helper.rb +26 -0
  31. data/lib/sir_trevor_rails/version.rb +3 -0
  32. data/lib/sir_trevor_rails/view_resolver.rb +13 -0
  33. data/lib/sir_trevor_rails.rb +30 -0
  34. data/sir_trevor_rails.gemspec +39 -0
  35. data/spec/internal/app/models/custom_block.rb +5 -0
  36. data/spec/internal/app/models/post.rb +2 -0
  37. data/spec/internal/config/database.yml +3 -0
  38. data/spec/internal/config/routes.rb +3 -0
  39. data/spec/internal/db/schema.rb +7 -0
  40. data/spec/internal/log/.gitignore +1 -0
  41. data/spec/internal/public/favicon.ico +0 -0
  42. data/spec/spec_helper.rb +16 -0
  43. data/spec/unit/block_array_spec.rb +66 -0
  44. data/spec/unit/block_spec.rb +66 -0
  45. data/spec/unit/custom_block_spec.rb +19 -0
  46. data/spec/unit/has_sir_trevor_content_spec.rb +38 -0
  47. metadata +254 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e0440542cac7ceda76800ef5d839ce166aea6a96
4
+ data.tar.gz: 63bfbecf7f48260f978fd284bf773ec1cc8287c2
5
+ SHA512:
6
+ metadata.gz: 41c835b01d6f5fd0bf4540ba2a3c65d3fcf70c43de7586ab3048fae21025bd05045c70c4afca5a9671dbbfe3a774e8e9f7a97dd9c3b97ff1840d7bf281135a3f
7
+ data.tar.gz: 7621bdbeae052096553e9af079169a8f600aef8e8733acfdf02e0b3f91618455c8a44b3bcec27a0eb382fbb55fd52b1cfc0d32c9cd6e3f4d3cdf3c19821b9013
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .DS_Store
3
+ Gemfile.lock
4
+ spec/internal/db/combustion_test.sqlite
data/CHANGELOG ADDED
@@ -0,0 +1,13 @@
1
+ v0.4.0:
2
+ date: 2014-05-20
3
+ changes:
4
+ - Renamed gem sir_trevor_rails (used to be sir-trevor-rails)
5
+ - Removed sir trevor JS and all its dependencies (should install files manually or from bower from now on)
6
+ - Removed all the view helpers appart from sir_trevor_markdown (render_sir_trevor, render_sir_trevor_block, render_sir_trevor_image, sir_trevor_image_tag, parse_sir_trevor are all gone)
7
+ - Removed the form helper (no more sir_trevor_text_area)
8
+ - Added has_sir_trevor_content.rb as a concern for models with ST content
9
+ - Remove jQuery rails dependency
10
+ - Use view resolvers and to_partial_path to render ST content (instead of the view helper)
11
+ - Add block array class
12
+ - Add block classes
13
+ - Add lookup methods on the block array
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sir_trevor_rails.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013-2014 by ITV plc - http://www.itv.com
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Sir Trevor Rails
2
+
3
+ A Rails gem for integrating Sir Trevor JS into your Rails 3/4 application.
4
+
5
+ ## Upgrade guide from v0.4.0-rc.1
6
+
7
+ Version 0.4.0 represents a major refactor and contains significant API changes.
8
+
9
+ * The SirTrevor gem has been renamed from ``sir-trevor-rails`` to ``sir_trevor_rails`` you will need to update your Gemfile.
10
+ * There are no more form helpers or view helpers so relace ``f.sir_trevor_text_area :content`` with ``f.text_area :content``.
11
+ * SirTrevor JS and it's dependencies are no longer bundled with the gem and need to be downloaded and installed manually or with bower. [See the SirTrevor JS repo for more](https://github.com/madebymany/sir-trevor-js#plain-js).
12
+ * In your model, register your SirTrevor content like this ``sir_trevor_content :content`` where ``:content`` is the name of the field on your where you store SirTrevor content.
13
+ * In your views, you no longer need to use the ``render_sir_trevor`` helper. Instead, simply render your content like this ``<%= render @item.content %>``
14
+
15
+ ## Usage
16
+
17
+ Add Sir Trevor to your Gemfile
18
+
19
+ ```ruby
20
+ gem 'sir_trevor_rails'
21
+ ```
22
+
23
+ ```bash
24
+ bundle install
25
+ ```
26
+
27
+ Include Sir Trevor JS in your project following the instructions set out [here](http://madebymany.github.io/sir-trevor-js/docs.html)
28
+
29
+ ## Generators: Views
30
+
31
+ Grab all of the default block type partials by running the following generator command:
32
+
33
+ ```bash
34
+ rails g sir_trevor_rails:views
35
+ ```
36
+
37
+ This will copy all of the SirTrevor block partials into `app/views/sir_trevor/blocks/`
38
+
39
+ ## Rendering
40
+
41
+ In your models pass the attribute name of your Sir Trevor content to `sir_trevor_content`
42
+
43
+ ```ruby
44
+ sir_trevor_content :content
45
+ ```
46
+
47
+ In your view files, call render to display the Sir Trevor content
48
+
49
+ ```ruby
50
+ <%= render @item.content %>
51
+ ```
52
+
53
+ ## Handling image uploads
54
+
55
+ We don't provide a default image uploader out of the box, because everyone will have different requirements. To see an example of an image uploader, please refer to our Rails examples in the [Sir Trevor JS repository](https://github.com/madebymany/sir-trevor-js/tree/master/examples/rails/image-uploader).
56
+
57
+ ## Handling markdown
58
+
59
+ Use the ``sir_trevor_markdown`` method in your custom block partials to correctly parse the markdown in a block
60
+
61
+ ## Querying the block content
62
+
63
+ Use the following methods to query the Sir Trevor content
64
+
65
+ ```ruby
66
+ @item.content.has_block_of_type?(:image)
67
+ ```
68
+
69
+ Does this content have an image block?
70
+
71
+ ```ruby
72
+ @item.content.first_block_of_type(:video)
73
+ ```
74
+
75
+ Return the first video block in the content
76
+
77
+ ## Add custom methods for block content
78
+
79
+ Create an initializer ``config/initializers/sir_trevor_rails.rb``
80
+
81
+ Write your method in the initializer:
82
+
83
+ ```ruby
84
+ class SirTrevorRails::BlockArray
85
+ def your_custom_method_here
86
+ # some code
87
+ end
88
+ end
89
+ ```
90
+
91
+ Call your method on the ST content
92
+
93
+ ```ruby
94
+ @item.content.your_custom_method
95
+ ```
96
+
97
+ ## Generators: Blocks
98
+
99
+ Run the blocks generator to create templates for your custom blocks
100
+
101
+ ```bash
102
+ rails g sir_trevor_rails:block my_custom_block
103
+ ```
104
+
105
+ This will generate an html file for rendering the block, a javascript file for the editor and a ruby block class.
106
+
107
+ ## Block Classes
108
+
109
+ Ruby block classes can be used like decorators for the block content. See the [tweet block class](https://github.com/madebymany/sir-trevor-rails/blob/redesign-gem/lib/sir_trevor_rails/blocks/tweet_block.rb) for an example
110
+
111
+ ## Requirements
112
+
113
+
114
+ - Rails 3.x/4.x
115
+
116
+ ## To do
117
+
118
+ - Add tests
119
+
120
+ ## Licence
121
+
122
+ Sir Trevor Rails is released under the [MIT Licence](MIT-LICENSE)
123
+
124
+ ## Changelog
125
+
126
+ See the [CHANGELOG](CHANGELOG)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'spec'
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ end
@@ -0,0 +1 @@
1
+ <%= render sir_trevor_block_array.to_a %>
@@ -0,0 +1 @@
1
+ <h2><%= heading_block.text %></h2>
@@ -0,0 +1,5 @@
1
+ <% if image_block.file && image_block.file[:url] -%>
2
+ <figure class="st__content-block st__content-block--image">
3
+ <%= image_tag image_block.file[:url] %>
4
+ </figure>
5
+ <% end -%>
@@ -0,0 +1,3 @@
1
+ <div class="st__content-block st__content-block--list">
2
+ <%= sir_trevor_markdown list_block.text %>
3
+ </div>
@@ -0,0 +1,13 @@
1
+ <div class="st__content-block st__content-block--quote">
2
+ <div class="quote">
3
+ <div class="quote__content">
4
+ <%= sir_trevor_markdown quote_block.text %>
5
+ </div>
6
+
7
+ <% if quote_block.cite.present? %>
8
+ <div class="quote__cite">
9
+ <cite class="quote__cite-text">&ndash; <%= quote_block.cite %></cite>
10
+ </div>
11
+ <% end %>
12
+ </div>
13
+ </div>
@@ -0,0 +1,3 @@
1
+ <div class="st__content-block st__content-block--text">
2
+ <%= sir_trevor_markdown text_block.text %>
3
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="st__content-block st__content-block--tweet">
2
+ <%= link_to image_tag(tweet_block.profile_image_url, class: 'img'), tweet_block.screen_name %>
3
+ <p>
4
+ <%= tweet_block.render_tweet_body %>
5
+ </p>
6
+ <cite>From <%= link_to tweet_block.at_name, tweet_block.screen_name %> on Twitter:</cite>
7
+ <time datetime="<%= tweet_block.created_at %>">(<%= link_to Time.parse(tweet_block.created_at), tweet_block.status_url %>)</time>
8
+ </div>
9
+
@@ -0,0 +1,4 @@
1
+ <div class="st__content-block st__content-block--video">
2
+ <iframe src="//player.vimeo.com/video/<%= vimeo.remote_id %>?title=1&amp;byline=1&amp;portrait=1&amp;autoplay=0"
3
+ width="640" height="360" frameborder="0" allowfullscreen></iframe>
4
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="st__content-block st__content-block--video">
2
+ <iframe src="//www.youtube.com/embed/<%= youtube.remote_id %>?wmode=transparent"
3
+ width="640" height="360" frameborder="0" allowfullscreen></iframe>
4
+ </div>
@@ -0,0 +1,12 @@
1
+ require 'active_model/validator'
2
+
3
+ class IsJsonValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, value)
5
+ @json = MultiJson.load(value, symbolize_keys: true)
6
+ record.errors.add(attribute, "is empty") if @json.empty?
7
+ rescue TypeError => e
8
+ record.errors.add(attribute, "is not valid JSON: #{e.message}")
9
+ rescue JSON::JSONError => e
10
+ record.errors.add(attribute, "is not valid JSON: #{e.message}")
11
+ end
12
+ end
data/config.ru ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require :default, :development
5
+
6
+ Combustion.initialize! :all
7
+ run Combustion::Application
@@ -0,0 +1,33 @@
1
+ require 'rails/generators'
2
+
3
+ module SirTrevorRails
4
+ module Generators
5
+ class BlockGenerator < Rails::Generators::NamedBase
6
+
7
+ def self.source_root
8
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
9
+ end
10
+
11
+ def create_block
12
+
13
+ # Copy the JS
14
+ copy_file "_block.js", "app/assets/javascripts/sir_trevor/blocks/#{name}.js"
15
+
16
+ gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /SirTrevor\.Blocks\.Example/, "SirTrevor.Blocks.#{name.capitalize}"
17
+ gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /return "Example"/, "return: '#{name.capitalize}'"
18
+ gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /type: 'example'/, "type: '#{name.downcase}'"
19
+
20
+ # Copy the HTML
21
+ copy_file "_block.html.erb", "app/views/sir_trevor/blocks/_#{name}_block.html.erb"
22
+ gsub_file "app/views/sir_trevor/blocks/_#{name}_block.html.erb", /\s(-block)/, " #{name}-block"
23
+ gsub_file "app/views/sir_trevor/blocks/_#{name}_block.html.erb", /\s(_block)/, " #{name}_block"
24
+
25
+ # Copy the BlockDecorator
26
+ copy_file "_block.rb", "app/sir_trevor_blocks/#{name}_block.rb"
27
+ gsub_file "app/sir_trevor_blocks/#{name}_block.rb", /ExampleBlock/, " #{name}Block"
28
+
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ <div class="content-block example-block">
2
+ <%= example_block %>
3
+ </div>
@@ -0,0 +1,203 @@
1
+ /*
2
+ An example of a SirTrevor.Block
3
+ --
4
+ Author: C J Bell @ madebymany
5
+ */
6
+
7
+ SirTrevor.Blocks.Example = (function(){
8
+
9
+ return SirTrevor.Block.extend({
10
+
11
+ // String; Names the block
12
+ // Note – please use underscores when naming
13
+ // Eg example_block should be ExampleBlock
14
+ type: 'example',
15
+
16
+ // Function; the title displayed in the toolbar
17
+ // Can return a translated string (if required)
18
+ title: function() {
19
+ // return i18n.t('blocks:example:title');
20
+ return "Example";
21
+ },
22
+
23
+ // Boolean; show this blockType of the toolbar
24
+ toolbarEnabled: true,
25
+
26
+ // Block Mixins
27
+ // Allow different UI components / methods to be mixed into the block
28
+
29
+ // Enable drop functionality on the block
30
+ droppable: false,
31
+
32
+ // Enable paste functionality (to paste URLS etc)
33
+ pastable: false,
34
+
35
+ // Enable an upload button to be added
36
+ // Mixins Ajaxable automatically
37
+ // Exposes an uploader method
38
+ // Usage: this.uploader(file, success, failure)
39
+ uploadable: false,
40
+
41
+ // Enable queued remote fetching
42
+ // Exposes a small wrapper around the $.ajax method
43
+ // Usage: this.fetch(ajaxOptions, success, failure)
44
+ fetchable: false,
45
+
46
+ // Add an ajax queue to the block
47
+ // Added to uploadable & fetchable automatically
48
+ ajaxable: false,
49
+
50
+ // Overwritable mixin options:
51
+ // --
52
+ drop_options: {
53
+ // String; (can use underscore template tags)
54
+ // Defines the HTML for the dropzone template
55
+ html: "<div class='st-block__dropzone'></div>",
56
+ // Boolean;
57
+ // On re-order, should we re-render this item.
58
+ // Useful for when re-ordering iframes (like Twitter)
59
+ re_render_on_reorder: false
60
+ },
61
+
62
+ paste_options: {
63
+ // String; (can use underscore template tags)
64
+ // Defines the HTML for the paste template
65
+ html: "<input type=\"text\" class=\"st-paste-block\">"
66
+ },
67
+
68
+ upload_options: {
69
+ // String; (can use underscore template tags)
70
+ // Defines the HTML for the upload template
71
+ html: "<input type=\"file\" type=\"st-file-upload\">"
72
+ },
73
+
74
+ formattable: true,
75
+
76
+ // String or Function; The HTML for the inner portion of the editor block
77
+ // In this example, the editorHTML is an editable input div (like we use for a TextBlock)
78
+
79
+ // Classes:
80
+ // st-required – indicates this input must be present to pass validation
81
+ // st-text-block – gives the block the ability to use the formatting controls
82
+
83
+ editorHTML: function() {
84
+ return "<div class='st-text-block' contenteditable='true'></div>";
85
+ },
86
+
87
+ // Element shorthands
88
+ // --
89
+ // this.$el
90
+ // this.el
91
+ // this.$inner (the inner container for the block)
92
+ // this.$editor (contains all the UI inputs for the block)
93
+ // this.$inputs (contains all the UI inputs for blocks that are uploadable / droppable / pastable)
94
+ // this.getTextBlock() (shorthand for this.$el.find('.st-text-block'))
95
+ // this.$(selector) (shorthand for this.$el.find(selector))
96
+
97
+ // Validations
98
+ // --
99
+ // Required fields (with .st-required class) always get validted
100
+ // Called using the validateField method
101
+ // Set a data-st-name="Field Name" on your required inputs to use it in the validation fail message
102
+
103
+ // Array; defines custom validator methods to call
104
+ validations: ['myCustomValidator'],
105
+
106
+ // Example custom validator
107
+ myCustomValidator: function() {
108
+ var field = this.$('.a-field');
109
+
110
+ if (field.val() === 'herp derp') {
111
+ this.setError(field, "A validation fail message");
112
+ }
113
+ },
114
+
115
+ // Function; Executed on render of the block if some data is provided.
116
+ // LoadData gives us a means to convert JSON data into the editor dom
117
+ // In this example we convert the text from markdown to HTML and show it inside the element
118
+ loadData: function(data){
119
+ this.getTextBlock().html(SirTrevor.toHTML(data.text, this.type));
120
+ },
121
+
122
+ // Function; Executed on save of the block, once the block is validated
123
+ // toData expects a way for the block to be transformed from inputs into structured data
124
+ // The default toData function provides a pretty comprehensive way of turning data into JSON
125
+ // In this example we take the text data and save it to the data object on the block
126
+ toData: function(){
127
+ var dataObj = {};
128
+
129
+ var content = this.getTextBlock().html();
130
+ if (content.length > 0) {
131
+ dataObj.text = SirTrevor.toMarkdown(content, this.type);
132
+ }
133
+
134
+ this.setData(dataObj);
135
+ },
136
+
137
+ // Function; Returns true or false whether there is data in the block
138
+ isEmpty: function() {
139
+ return _.isEmpty(this.saveAndGetData()); // Default implementation
140
+ },
141
+
142
+ // Other data functions
143
+ // --
144
+ // getData – returns the data in the store
145
+ // save - Invokes the toData method
146
+ // saveAndReturnData - Saves and returns the entire store
147
+ // saveAndGetData - Save and only return the data part of the store
148
+
149
+
150
+ // Function; Hook executed at the end of the block rendering method.
151
+ // Useful for initialising extra pieces of UI or binding extra events.
152
+ // In this example we add an extra button, just because.
153
+ onBlockRender: function() {
154
+ this.$editor.append($('<button>', {
155
+ click: function() {
156
+ alert('Yo dawg, you clicked my button');
157
+ }
158
+ }));
159
+ },
160
+
161
+ // Function; Optional hook method executed before the rendering of a block
162
+ // Beware, $el and any shorthand element variables won't be setup here.
163
+ beforeBlockRender: function() {},
164
+
165
+ // Function; Executed once content has been dropped onto the dropzone of this block
166
+ // Only required if you have enabled dropping and have provided a dropzone for this block
167
+ // Always is passed the ev.transferData object from the drop
168
+ // Please see the image block (https://github.com/madebymany/sir-trevor-js/blob/master/src/blocks/image.js) for an example
169
+ onDrop: function(transferData) {},
170
+
171
+ // Function; executed once content has been pasted into a pastable block
172
+ // See the tweet block as an example (https://github.com/madebymany/sir-trevor-js/blob/master/src/blocks/tweet.js)
173
+ onContentPasted: function(event) {},
174
+
175
+ // Block level messages
176
+ // --
177
+ // addMessage(msg, additionalClass)
178
+ // Adds a new message onto the block
179
+
180
+ // resetMessages()
181
+ // Clears all existing messages
182
+
183
+ // Helper methods
184
+ // --
185
+ // loading()
186
+ // ready()
187
+ // hasTextBlock()
188
+ // remove()
189
+
190
+ // Function; Any extra markdown parsing can be defined in here.
191
+ // Returns; String (Required)
192
+ toMarkdown: function(markdown) {
193
+ return markdown.replace(/^(.+)$/mg,"> $1");
194
+ },
195
+
196
+ // Function; Any extra HTML parsing can be defined in here.
197
+ // Returns; String (Required)
198
+ toHTML: function(html) {
199
+ return html;
200
+ }
201
+ });
202
+
203
+ })();
@@ -0,0 +1,2 @@
1
+ class ExampleBlock < SirTrevorRails::Block
2
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+
3
+ module SirTrevorRails
4
+ module Generators
5
+ class ViewsGenerator < Rails::Generators::Base
6
+
7
+ def self.source_root
8
+ @source_root ||= SirTrevorRails::Engine.root
9
+ end
10
+
11
+ def views
12
+ directory "app/views/sir_trevor"
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,63 @@
1
+ require 'ostruct'
2
+
3
+ module SirTrevorRails
4
+ class Block < OpenStruct
5
+
6
+ def self.from_hash(hash, parent)
7
+ hash = hash.deep_dup
8
+ self.type_klass(hash).new(hash, parent)
9
+ end
10
+
11
+ def initialize(hash, parent)
12
+ @as_json = hash
13
+ @parent = parent
14
+ @type = hash[:type].to_sym
15
+
16
+ super(hash[:data])
17
+ end
18
+
19
+ attr_reader :parent, :type, :as_json
20
+
21
+ def to_partial_path
22
+ "sir_trevor/blocks/" << self.class.name.demodulize.underscore
23
+ end
24
+
25
+ private
26
+
27
+ # Infers the block class.
28
+ # Safe lookup that tries to identify user created block class.
29
+ #
30
+ # @param [Symbol] type
31
+ def self.block_class(type)
32
+ block_name = "#{type.to_s.camelize}Block"
33
+ begin
34
+ block_name.constantize
35
+ rescue NameError
36
+ block_class!(block_name)
37
+ end
38
+ end
39
+
40
+ # Infers the block class.
41
+ # Failover from block_class.
42
+ # Safe lookup against the SirTevor::Blocks namespace
43
+ # If no block is found, create one with given name and inherit from Block class
44
+ #
45
+ # @param [Constant] block_name
46
+ def self.block_class!(block_name)
47
+ begin
48
+ SirTrevorRails::Blocks.const_get(block_name)
49
+ rescue NameError
50
+ SirTrevorRails::Blocks.const_set(block_name, Class.new(Block))
51
+ end
52
+ end
53
+
54
+ def self.type_klass(hash)
55
+ if self == Block
56
+ block_class(hash[:type].to_sym)
57
+ else
58
+ self
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ module SirTrevorRails
2
+ class BlockArray < Array
3
+
4
+ def self.from_json(str, parent = nil)
5
+ blocks = MultiJson.load(str, symbolize_keys: true)
6
+ blocks = blocks[:data] if blocks.is_a?(Hash)
7
+ blocks.map! { |block_obj| SirTrevorRails::Block.from_hash(block_obj, parent) }
8
+ new blocks
9
+ end
10
+
11
+ def has_block_of_type?(type)
12
+ klass = Block.block_class(type)
13
+ any? { |b| b.is_a? klass }
14
+ end
15
+
16
+ def first_block_of_type(type)
17
+ klass = Block.block_class(type)
18
+ detect { |b| b.is_a? klass }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ require 'twitter-text'
2
+
3
+ module SirTrevorRails
4
+ module Blocks
5
+ class TweetBlock < SirTrevorRails::Block
6
+
7
+ include ActionView::Helpers::SanitizeHelper
8
+
9
+ def render_tweet_body
10
+ sanitize Twitter::Autolink.auto_link(
11
+ self.text,
12
+ url_entities: (self.entities.values_at(:urls, :media).flatten.compact.uniq rescue nil)
13
+ ), tags: %w{a span}, attributes: %w{class href rel target}
14
+ end
15
+
16
+ def profile_url
17
+ "//twitter.com/" << self.user[:screen_name]
18
+ end
19
+
20
+ def screen_name
21
+ self.user[:screen_name]
22
+ end
23
+
24
+ def at_name
25
+ "@" << screen_name
26
+ end
27
+
28
+ def profile_image_url(size="bigger")
29
+ "//twitter.com/api/users/profile_image/" << self.user[:screen_name] <<
30
+ "?size=" << size
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module SirTrevorRails
2
+ module Blocks
3
+ class VideoBlock < SirTrevorRails::Block
4
+ def to_partial_path
5
+ "sir_trevor/blocks/videos/" << self.source
6
+ end
7
+ end
8
+ end
9
+ end