Class: PostType

Inherits:
Object
  • Object
show all
Extended by:
ClassLevelInheritableAttributes
Includes:
Extlib::Hook
Defined in:
lib/turbine-core/post_type.rb

Direct Known Subclasses

Article, Audio, Chat, Link, Photo, Quote, Review, Video

Constant Summary collapse

DEFAULT_FIELDS =
[:published_at, :status, :slug, :trackbacks, :type, :tags]
NON_EDITABLE_FIELDS =
[:trackbacks, :type, :published_at]
@@preferred_order =

cattr_accessor

[]

Constants included from ClassLevelInheritableAttributes

ClassLevelInheritableAttributes::PRIMITIVES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClassLevelInheritableAttributes

cattr_inheritable, inherited

Constructor Details

#initialize(stuff = nil) ⇒ PostType

Returns a new instance of PostType.



272
273
274
275
276
277
# File 'lib/turbine-core/post_type.rb', line 272

def initialize(stuff = nil)
  if stuff
    self.content = stuff
    # sanitize_content_fields
  end
end

Instance Attribute Details

#contentObject

where everything is stored



66
67
68
# File 'lib/turbine-core/post_type.rb', line 66

def content
  @content
end

Class Method Details

.allow(*list) ⇒ Object



74
75
76
# File 'lib/turbine-core/post_type.rb', line 74

def self.allow(*list)
  self.allowed_fields_list = [self.allowed_fields_list, list.make_attrs].flatten.uniq
end

.auto_detect(text) ⇒ Object

runs through the list of children looking for one that will work



248
249
250
251
252
# File 'lib/turbine-core/post_type.rb', line 248

def self.auto_detect(text)
  list = self.preferred_order.blank? ? @all_children : self.preferred_order
  
  list.each { |l| return l.new(text) if l.detect?(text) }
end

.default(field, &block) ⇒ Object



114
115
116
117
# File 'lib/turbine-core/post_type.rb', line 114

def self.default(field, &block)
  field = field.make_attr
  self.defaults_blocks[field] = block if allowed_fields_list.include? field
end

.detect?(text) ⇒ Boolean

can be overriden to provide auto detection of type from a block of text

Examples:

def self.detect?(text)
  has_keys? text, :title, :body
end

def self.detect?(text)
  has_required? text
end

def self.detect?(text)
  has_one_or_more? text, :me
end

Returns:

  • (Boolean)


212
213
214
# File 'lib/turbine-core/post_type.rb', line 212

def self.detect?(text)
  false
end

.dynamic(field, &block) ⇒ Object



123
124
125
126
127
# File 'lib/turbine-core/post_type.rb', line 123

def self.dynamic(field, &block)
  field = field.make_attr
  self.dynamic_blocks[field] = block
  allow(field)
end

.fields(*list) ⇒ Object

basic setup methods for types of posts



69
70
71
72
# File 'lib/turbine-core/post_type.rb', line 69

def self.fields(*list)
  self.fields_list = list.make_attrs
  self.allowed_fields_list = [DEFAULT_FIELDS, list.make_attrs].flatten.uniq
end

.get_pairs(text) ⇒ Object



234
235
236
# File 'lib/turbine-core/post_type.rb', line 234

def self.get_pairs(text)
  StringImporter.new(self).import(text)
end

.get_pairs_count(text, fields) ⇒ Object



238
239
240
241
# File 'lib/turbine-core/post_type.rb', line 238

def self.get_pairs_count(text, fields)
  pairs = get_pairs(text)
  pairs.reject { |pair| !fields.include?(pair.keys.first) }
end

.has_keys?(text, *fields) ⇒ Boolean

useful for detection

Returns:

  • (Boolean)


217
218
219
220
# File 'lib/turbine-core/post_type.rb', line 217

def self.has_keys?(text, *fields)
  needed = fields.make_attrs
  get_pairs_count(text, needed).length == needed.length
end

.has_more_than?(text, field, amount) ⇒ Boolean

Returns:

  • (Boolean)


230
231
232
# File 'lib/turbine-core/post_type.rb', line 230

def self.has_more_than?(text, field, amount)
  get_pairs_count(text, [field]).length > amount
end

.has_more_than_one?(text, field) ⇒ Boolean

Returns:

  • (Boolean)


222
223
224
# File 'lib/turbine-core/post_type.rb', line 222

def self.has_more_than_one?(text, field)
  has_more_than? text, field, 1
end

.has_one_or_more?(text, field) ⇒ Boolean

Returns:

  • (Boolean)


226
227
228
# File 'lib/turbine-core/post_type.rb', line 226

def self.has_one_or_more?(text, field)
  has_more_than? text, field, 0
end

.has_required?(text) ⇒ Boolean

Returns:

  • (Boolean)


243
244
245
# File 'lib/turbine-core/post_type.rb', line 243

def self.has_required?(text)
  has_keys? text, *self.required_fields_list
end

.heading(field) ⇒ Object



94
95
96
97
# File 'lib/turbine-core/post_type.rb', line 94

def self.heading(field)
  field = field.make_attr
  self.heading_field = field if fields_list.include? field
end

.html(&block) ⇒ Object



119
120
121
# File 'lib/turbine-core/post_type.rb', line 119

def self.html(&block)
  self.html_block = block
end

.markdown(*list) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/turbine-core/post_type.rb', line 129

def self.markdown(*list)
  self.markdown_fields =  [
                            self.markdown_fields,
                            list.make_attrs.reject { |l| !fields_list.include? l }
                          ].flatten.uniq
                          
  self.allowed_fields_list = [
                                self.allowed_fields_list, 
                                self.markdown_fields.collect { |m| m.html }
                              ].flatten.uniq
end

.preferred_orderObject



37
38
39
# File 'lib/turbine-core/post_type.rb', line 37

def self.preferred_order
  @@preferred_order
end

.preferred_order=(new_order) ⇒ Object



40
41
42
# File 'lib/turbine-core/post_type.rb', line 40

def self.preferred_order=(new_order)
  @@preferred_order = new_order
end

.primary(field) ⇒ Object



85
86
87
88
89
90
91
92
# File 'lib/turbine-core/post_type.rb', line 85

def self.primary(field)
  field = field.make_attr
  
  if fields_list.include? field
    self.primary_field = field
    markdown field # primary is a markdown field by default
  end
end

.required(*list) ⇒ Object



78
79
80
81
82
83
# File 'lib/turbine-core/post_type.rb', line 78

def self.required(*list)
  self.required_fields_list = [
                                self.required_fields_list,
                                list.make_attrs.reject { |l| !fields_list.include? l }
                              ].flatten.uniq
end

.special(field, &block) ⇒ Object



99
100
101
102
# File 'lib/turbine-core/post_type.rb', line 99

def self.special(field, &block)
  field = field.make_attr
  self.specials_blocks[field] = block if allowed_fields_list.include? field
end

.string_for(field, &block) ⇒ Object



104
105
106
107
# File 'lib/turbine-core/post_type.rb', line 104

def self.string_for(field, &block)
  field = field.make_attr
  self.string_for_blocks[field] = block if allowed_fields_list.include? field
end

Instance Method Details

#blank_attr?(key) ⇒ Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/turbine-core/post_type.rb', line 171

def blank_attr?(key)
  get_attr(key).blank?
end

#commit_array(pairs_array) ⇒ Object



313
314
315
316
317
# File 'lib/turbine-core/post_type.rb', line 313

def commit_array(pairs_array)
  pairs_array.each do |pairs_hash|
    commit_hash(pairs_hash)
  end
end

#commit_hash(pairs_hash) ⇒ Object



307
308
309
310
311
# File 'lib/turbine-core/post_type.rb', line 307

def commit_hash(pairs_hash)
  pairs_hash.each do |key, value|
    set_attr(key, value)
  end
end

#default_statusObject



389
390
391
# File 'lib/turbine-core/post_type.rb', line 389

def default_status
  :published
end

#delete_attr(key) ⇒ Object Also known as: remove_attr, del_attr



190
191
192
# File 'lib/turbine-core/post_type.rb', line 190

def delete_attr(key)
  set_attr(key.make_attr, nil)
end

#eval_defaultsObject



319
320
321
322
323
324
325
# File 'lib/turbine-core/post_type.rb', line 319

def eval_defaults
  if valid?
    self.class.defaults_blocks.each do |key, block|
      set_default(key, self.instance_eval(&block))
    end
  end
end

#fill_default_fieldsObject



347
348
349
350
351
# File 'lib/turbine-core/post_type.rb', line 347

def fill_default_fields
  set_default(:published_at, Time.now.utc)
  set_default(:status, default_status)
  eval_defaults
end

#generate_slugObject

OPTIMIZE: this slug generation is ugly



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/turbine-core/post_type.rb', line 353

def generate_slug # OPTIMIZE: this slug generation is ugly
  result = ''

  unless self.class.always_use_uuid
    result = get_attr(self.class.heading_field, false).to_s.dup unless self.class.heading_field.blank?

    if result.blank?
      result = get_attr(self.class.primary_field, false).to_s.dup unless self.class.primary_field.blank?
    end

    if result.blank?
      self.class.required_fields_list.each do |required_field|
        unless get_attr(required_field).blank?
          result = get_attr(required_field).to_s.dup
          break
        end#of unless
      end#of each
    end#of if

    result.slugify!
  end#of unless

  if result.blank? || !slug_is_unique
    result = uuid
  end

  result
end

#get_attr(key, html = true) ⇒ Object

TODO: get_attr should return a default if it’s blank



180
181
182
183
184
185
186
187
188
# File 'lib/turbine-core/post_type.rb', line 180

def get_attr(key, html = true)
  key = key.make_attr
  
  if html && self.class.markdown_fields.include?(key)
    @content[key.html]
  else
    @content[key]
  end
end

#get_attr?(key) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/turbine-core/post_type.rb', line 175

def get_attr?(key)
  !blank_attr?(key)
end

#get_string_for(key) ⇒ Object



327
328
329
330
331
332
333
# File 'lib/turbine-core/post_type.rb', line 327

def get_string_for key
  if self.class.string_for_blocks[key]
    self.class.string_for_blocks[key].call(get_attr(key))
  else
    get_attr(key)
  end
end

#haml(data, options = {}, locals = {}) ⇒ Object



417
418
419
# File 'lib/turbine-core/post_type.rb', line 417

def haml(data, options = {}, locals = {})
  ::Haml::Engine.new(data, options).render(self, locals)
end

#import(stuff) ⇒ Object



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/turbine-core/post_type.rb', line 289

def import(stuff)
  importer = Kernel.const_get(stuff.class.name+'Importer').new(self.class)
  
  # The result sent back by an importer is either:
  #   Array:
  #     [{ :one => 'stuff' }, { :two => 'stuff' }]
  #   Hash:
  #     { :one => 'stuff', :two => 'stuff' }
  result = stuff.blank? ? {} : importer.import(stuff)
  
  case result
  when Array
    commit_array(result)
  when Hash
    commit_hash(result)
  end
end

#post_to_trackbacksObject



393
394
395
# File 'lib/turbine-core/post_type.rb', line 393

def post_to_trackbacks
  false
end

#sanitize_content_fieldsObject



335
336
337
# File 'lib/turbine-core/post_type.rb', line 335

def sanitize_content_fields
  @content.reject! { |key, value| !self.class.allowed_fields_list.include?(key) }
end

#saveObject



279
280
281
282
283
284
285
286
287
# File 'lib/turbine-core/post_type.rb', line 279

def save
  if valid?
    truncate_slug if self.class.truncate_slugs
    fill_default_fields
    send_to_storage
  else
    false
  end
end

#send_to_storageObject

send to the db or whatever



339
340
341
# File 'lib/turbine-core/post_type.rb', line 339

def send_to_storage # send to the db or whatever
  false
end

#set_attr(key, value) ⇒ Object

TODO: when setting an attr, we should also run it’s special block if it has one



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/turbine-core/post_type.rb', line 142

def set_attr(key, value)
  key = key.make_attr
  
  unless value.blank?
    # run specials if there is one, or just set the key
    if self.class.specials_blocks[key]
      @content[key] = self.class.specials_blocks[key].call(value)
    else
      @content[key] = value
    end
    
    # run markdowns if there is one
    if self.class.markdown_fields.include?(key)
      markdown = Markdown.new @content[key].strip
      @content[key.html] = markdown.to_html.strip
    else
      @content.delete(key.html)
    end
  else
    # remove any blank valued keys
    @content.delete(key)
    @content.delete(key.html)
  end
end

#set_default(key, value) ⇒ Object



167
168
169
# File 'lib/turbine-core/post_type.rb', line 167

def set_default(key, value)
  set_attr(key, value) if blank_attr?(key)
end

#slug_is_uniqueObject

validate uniqueness



343
344
345
# File 'lib/turbine-core/post_type.rb', line 343

def slug_is_unique # validate uniqueness
  true
end

#to_htmlObject



421
422
423
424
425
426
427
# File 'lib/turbine-core/post_type.rb', line 421

def to_html
  unless self.class.html_block.blank?
    self.instance_eval(&self.class.html_block)
  else
    Markdown.new(to_s).to_html
  end
end

#to_sObject



401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/turbine-core/post_type.rb', line 401

def to_s
  fields_to_parse = self.class.fields_list - [self.class.primary_field] + DEFAULT_FIELDS - NON_EDITABLE_FIELDS
  
  result = fields_to_parse.map do |field|
    unless blank_attr?(field)
      "#{field}: #{get_string_for(field)}" 
    end#unless
  end.compact.join("\n")
  
  unless self.class.primary_field.blank? || blank_attr?(self.class.primary_field)
    result << "\n\n" + get_attr(self.class.primary_field, false)
  end
  
  result.strip
end

#truncate_slug(letter_count = 50) ⇒ Object



382
383
384
385
386
387
# File 'lib/turbine-core/post_type.rb', line 382

def truncate_slug(letter_count = 50)
  unless get_attr(:slug).blank?
    new_slug = get_attr(:slug).gsub(/^(.{#{letter_count}})(.*)/) { $1.slugify }
    set_attr(:slug, new_slug)
  end
end

#uuidObject



397
398
399
# File 'lib/turbine-core/post_type.rb', line 397

def uuid
  UUID.timestamp_create.to_s
end

#valid?Boolean

of content=

Returns:

  • (Boolean)


260
261
262
263
264
265
266
267
268
269
270
# File 'lib/turbine-core/post_type.rb', line 260

def valid? # TODO: this doesn't work if there are no required fields and the slug is not unique
  v = true
  
  if self.class.required_fields_list.blank?
    v = false unless self.class.required_fields_list.reject { |item| !get_attr(item).blank? }.blank?
  end
  
  v = false unless slug_is_unique
  
  v
end