html-schema 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ class HTMLSchema
2
+ # This model module is the standard API.
3
+ class API
4
+ class Object < HTMLSchema::Object
5
+ def microdata
6
+ @microdata ||= HTMLSchema.instance.microdata[_name]
7
+ end
8
+
9
+ def microformat
10
+ @microformat ||= HTMLSchema.instance.microformat[_name]
11
+ end
12
+
13
+ def to_microdata
14
+ microdata.to_hash
15
+ end
16
+
17
+ def to_microformat
18
+ microformat.to_hash
19
+ end
20
+
21
+ def to_hash
22
+ to_microdata.merge(to_microformat)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ class HTMLSchema
2
+ class Attribute < HTMLSchema::Object
3
+ attr_accessor :type, :value, :options, :required
4
+
5
+ def initialize(name, options = {}, &block)
6
+ @_name = name
7
+ @value = options
8
+ @parent = options[:parent]
9
+ @as = options[:as] || name
10
+ @classes = Array(as).map(&:to_s)
11
+ @required = options[:required] == true
12
+
13
+ @options = options.except(:as, :parent, :required, :type)
14
+ @options.each do |key, value|
15
+ @options[key] = value.to_s
16
+ end
17
+ end
18
+
19
+ def inspect
20
+ "#<#{self.class.name} name: #{_name.inspect}, value: #{value.inspect}>"
21
+ end
22
+
23
+ # ISO 8601 date format
24
+ def format(value)
25
+ case type
26
+ when :date
27
+ ::Date.parse(value)
28
+ else
29
+ value.to_s
30
+ end
31
+ end
32
+
33
+ def value=(value)
34
+ @value = format(value)
35
+ end
36
+
37
+ class << self
38
+ def attribute?
39
+ true
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ class HTMLSchema
2
+ class Configuration
3
+ attr_accessor :microdata, :microformat
4
+
5
+ def initialize
6
+ @microdata = true
7
+ @microformat = true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ class HTMLSchema
2
+ module DSL
3
+ def type(name, options = {}, &block)
4
+ types[name] = "#{self.name}::Object".constantize.new(name, options, &block)
5
+ end
6
+
7
+ def types
8
+ @types ||= {}
9
+ end
10
+
11
+ def root
12
+ @root ||= types.values.first
13
+ end
14
+
15
+ def [](key)
16
+ types[key]
17
+ end
18
+
19
+ def []=(key, value)
20
+ types[key] = value
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ class HTMLSchema
2
+ module Helper
3
+ def htmlschema(*args)
4
+ options = args.extract_options!
5
+ object = HTMLSchema.instance
6
+ args.each { |i| object = object.send(i) }
7
+ object.to_hash.merge(options)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,450 @@
1
+ class HTMLSchema
2
+ class Microdata
3
+ extend HTMLSchema::DSL
4
+
5
+ type :object do
6
+ attribute :name
7
+ attribute :title
8
+ attribute :url
9
+ attribute :description
10
+ attribute :image
11
+
12
+ type :contact, :as => :Contact do
13
+ attribute :kind, :as => :contactType # sales contact, PR, etc.
14
+ attribute :email
15
+ attribute :fax, :as => :faxNumber
16
+ attribute :phone, :as => :telephone
17
+
18
+ type :address, :as => :PostalAddress do
19
+ attribute :street, :as => :streetAddress
20
+ attribute :city, :as => :addressLocality
21
+ attribute :state, :as => :addressRegion
22
+ attribute :postal_code, :as => :postalCode
23
+ attribute :post_office_box, :as => :postOfficeBoxNumber
24
+ attribute :country, :as => :addressCountry#, :type => :place, :source => :country
25
+ end
26
+ end
27
+
28
+ type :composition, :as => :Composition do
29
+ attribute :abstract, :as => :about, :type => :base
30
+ attribute :average_rating, :as => :aggregateRating, :type => :rating
31
+ attribute :awards
32
+ attribute :rating, :as => :contentRating, :type => :rating
33
+ attribute :genre
34
+ attribute :headline
35
+ # http://tools.ietf.org/html/bcp47
36
+ attribute :language, :as => :inLanguage
37
+ attribute :interaction_count, :as => :interactionCount
38
+ attribute :family_friendly, :as => :isFamilyFriendly, :type => :boolean
39
+ attribute :tag, :as => :keywords
40
+ attribute :offer, :as => :offers, :type => :offer
41
+ attribute :review, :as => :reviews, :type => :review
42
+
43
+ # people and organizations
44
+ attribute :editor, :type => :person
45
+ attribute :author, :type => :person
46
+ attribute :organization, :as => :author, :type => :organization
47
+ attribute :publisher, :type => :organization
48
+
49
+ # addresses
50
+ attribute :location, :as => :contentLocation, :type => :place
51
+
52
+ # media
53
+ attribute :videa, :type => :media, :source => :video
54
+ attribute :encoding, :as => :encodings, :type => :media
55
+ attribute :audio, :type => :media, :source => :audio
56
+
57
+ # dates
58
+ attribute :published_at, :as => :datePublished, :type => :date
59
+
60
+ type :blog, :as => :Blog
61
+ type :book, :as => :Book
62
+ type :list, :as => :ItemList
63
+ type :map, :as => :Map
64
+ type :movie, :as => :Movie
65
+ type :recording, :as => :MusicRecording
66
+ type :painting, :as => :Painting
67
+ type :photo, :as => :Photograph
68
+ type :sculpture, :as => :Sculpture
69
+ type :episode, :as => :TVEpisode
70
+ type :season, :as => :TVSeason
71
+ type :series, :as => :TVSeries
72
+
73
+ type :article, :as => :Article do
74
+ attribute :body, :as => :articleBody
75
+ attribute :section, :as => :articleSection
76
+
77
+ type :article, :as => :Article do
78
+ type :blog_post, :as => :BlogPosting
79
+ type :news_article, :as => :NewsArticle
80
+ type :academic_article, :as => :ScholarlyArticle
81
+ end
82
+ end
83
+
84
+ type :media, :as => :MediaObject do
85
+ attribute :bitrate
86
+ attribute :size, :as => :contentSize
87
+ attribute :url, :as => :contentURL
88
+ attribute :embed_url, :as => :embedURL
89
+ attribute :duration, :as => :measurement
90
+ attribute :composition, :as => :encodesCreativeWork, :type => :composition
91
+ attribute :format, :as => :encodingFormat
92
+ attribute :expiration_date, :as => :expires, :type => :date
93
+ attribute :height, :type => :measurement
94
+ attribute :width, :type => :measurement
95
+ attribute :player, :as => :playerType # flash, silverlight, etc.
96
+ attribute :allowed_in, :as => :regionsAllowed, :type => :place
97
+ attribute :subscription_required, :as => :requiresSubscription, :type => :boolean
98
+ attribute :upload_date, :as => :uploadDate, :type => :date
99
+
100
+ type :audio, :as => :AudioObject
101
+ type :music_video, :as => :MusicVideoObject
102
+ type :video, :as => :VideoObject
103
+
104
+ type :image, :as => :ImageObject do
105
+ attribute :caption
106
+ attribute :exif, :as => :exifData
107
+ attribute :main, :as => :representativeOfPage, :type => :boolean
108
+ attribute :thumbnail, :type => :image
109
+ end
110
+ end
111
+
112
+ type :playlist, :as => :MusicPlaylist do
113
+ type :album, :as => :MusicAlbum
114
+ end
115
+
116
+ type :recipe, :as => :Recipe
117
+ type :review, :as => :Review do
118
+ attribute :item, :as => :itemReviewed, :type => :base
119
+ attribute :content, :as => :reviewBody
120
+ attribute :rating, :as => :reviewRating, :type => :rating
121
+ end
122
+
123
+ type :webpage, :as => :WebPage do
124
+ type :about_page, :as => :AboutPage
125
+ type :checkout_page, :as => :CheckoutPage
126
+ type :index_page, :as => :CollectionPage
127
+ type :contact_page, :as => :ContactPage
128
+ type :show_page, :as => :ItemPage
129
+ type :profile_page, :as => :ProfilePage
130
+ type :search_page, :as => :SearchResultsPage
131
+ end
132
+
133
+ type :widget, :as => :WebPageElement do
134
+ type :menu_item, :as => :SiteNavigationElement
135
+ type :table, :as => :Table
136
+ type :ad, :as => :WPAdBlock
137
+ type :footer, :as => :WPFooter
138
+ type :header, :as => :WPHeader
139
+ type :sidebar, :as => :WPSideBar
140
+ end
141
+ end
142
+
143
+ type :event, :as => :Event do
144
+ type :arts, :as => :VisualArtsEvent
145
+ type :business, :as => :BusinessEvent
146
+ type :chidrens, :as => :ChildrensEvent
147
+ type :comedy, :as => :ComedyEvent
148
+ type :dance, :as => :DanceEvent
149
+ type :education, :as => :EducationEvent
150
+ type :festival, :as => :Festival
151
+ type :food, :as => :FoodEvent
152
+ type :literary, :as => :LiteraryEvent
153
+ type :music, :as => :MusicEvent
154
+ type :sale, :as => :SaleEvent
155
+ type :social, :as => :SocialEvent
156
+ type :sports, :as => :SportsEvent
157
+ type :theater, :as => :TheaterEvent
158
+
159
+ attribute :attendee, :as => :attendees, :type => :person
160
+ attribute :duration, :type => :base, :source => :duration
161
+ attribute :end_date, :as => :endDate, :type => :date
162
+ attribute :start_date, :as => :startDate, :type => :date
163
+ attribute :location, :type => :address
164
+ attribute :place, :as => :location, :type => :place
165
+ attribute :offer, :as => :offers, :type => :offer
166
+ attribute :performer, :as => :performers, :type => :person
167
+ attribute :child_event, :as => :subEvents, :type => :event
168
+ attribute :parent_event, :as => :superEvent, :type => :event
169
+
170
+ type :user_interaction, :as => :UserInteraction do
171
+ type :user_blocks, :as => :UserBlocks
172
+ type :user_checkin, :as => :UserCheckins
173
+ type :user_comments, :as => :UserComments
174
+ type :user_downloads, :as => :UserDownloads
175
+ type :user_likes, :as => :UserLikes
176
+ type :user_page_views, :as => :UserPageVisits
177
+ type :user_plays, :as => :UserPlays
178
+ type :user_votes, :as => :UserPlusOnes
179
+ type :user_tweets, :as => :UserTweets
180
+ end
181
+ end
182
+
183
+ type :intangible, :as => :Intangible do
184
+ type :intangible, :as => :Enumeration do
185
+ type :intangible, :as => :BookFormatType do
186
+ type :intangible, :as => :EBook
187
+ type :intangible, :as => :Hardcover
188
+ type :intangible, :as => :Paperback
189
+ end
190
+ type :intangible, :as => :ItemAvailability do
191
+ type :intangible, :as => :Discontinued
192
+ type :intangible, :as => :InStock
193
+ type :intangible, :as => :InStoreOnly
194
+ type :intangible, :as => :OnlineOnly
195
+ type :intangible, :as => :OutOfStock
196
+ type :intangible, :as => :PreOrder
197
+ end
198
+ type :intangible, :as => :OfferItemCondition do
199
+ type :intangible, :as => :DamagedCondition
200
+ type :intangible, :as => :NewCondition
201
+ type :intangible, :as => :RefurbishedCondition
202
+ type :intangible, :as => :UsedCondition
203
+ end
204
+ end
205
+ type :intangible, :as => :Language
206
+ type :quantity, :as => :Quantity do
207
+ type :quantity, :as => :Distance
208
+ type :quantity, :as => :Duration
209
+ type :quantity, :as => :Energy
210
+ type :quantity, :as => :Mass
211
+ end
212
+
213
+ type :offer, :as => :Offer do
214
+ attribute :rating, :as => :aggregateRating, :type => :rating
215
+ attribute :availability, :source => :item_availability
216
+ attribute :condition, :as => :itemCondition, :source => :offer_item_condition
217
+ attribute :item, :as => :itemOffered, :type => :product
218
+ attribute :price
219
+ attribute :min_price, :as => :lowPrice
220
+ attribute :max_price, :as => :highPrice
221
+ attribute :currency, :as => :priceCurrency # in 3-letter ISO 4217 format
222
+ attribute :valid_until_date, :as => :priceValidUntil, :type => :date
223
+ attribute :review, :as => :reviews, :type => :review
224
+ attribute :seller, :type => :organization
225
+ attribute :count, :as => :offerCount
226
+
227
+ type :aggregate, :as => :AggregateOffer
228
+ end
229
+
230
+ type :intangible, :as => :StructuredValue do
231
+ type :rating do
232
+ attribute :best, :as => :bestRating
233
+ attribute :value, :as => :ratingValue
234
+ attribute :worst, :as => :worstRating
235
+ attribute :item, :as => :itemReviewed, :type => :base
236
+ attribute :rating_count, :as => :ratingCount
237
+ attribute :review_count, :as => :reviewCount
238
+ end
239
+ type :coordinates, :as => :GeoCoordinates do
240
+ attribute :elevation, :type => :measurement
241
+ attribute :latitude, :type => :measurement
242
+ attribute :longitude, :type => :measurement
243
+ end
244
+ end
245
+ end
246
+
247
+ type :organization, :as => :Organization do
248
+ attribute :address, :type => :address
249
+ attribute :average_rating, :as => :aggregateRating, :type => :rating
250
+ attribute :contact, :as => :contactPoints, :type => :contact
251
+ attribute :email
252
+ attribute :employee, :as => :employees, :type => :person
253
+ attribute :event, :as => :events, :type => :event
254
+ attribute :fax, :as => :faxNumber
255
+ attribute :founder, :as => :founders, :type => :person
256
+ attribute :founding_date, :as => :foundingDate, :type => :date
257
+
258
+ type :corporation, :as => :Corporation
259
+ type :educational_institution, :as => :EducationalOrganization do
260
+ type :college, :as => :CollegeOrUniversity
261
+ type :elementary_school, :as => :ElementarySchool
262
+ type :high_school, :as => :HighSchool
263
+ type :middle_school, :as => :MiddleSchool
264
+ type :pre_school, :as => :Preschool
265
+ type :school, :as => :School
266
+ end
267
+
268
+ type :governmental_institution, :as => :GovernmentOrganization
269
+
270
+ type :vendor, :as => :LocalBusiness do
271
+ attribute :branch_of, :as => :branchOf, :type => :organization
272
+ attribute :hours, :as => :openingHours
273
+ attribute :currency, :as => :currenciesAccepted # The currency accepted (in ISO 4217 currency format).
274
+ attribute :payment_method, :as => :paymentAccepted # Cash, credit card, etc.
275
+ attribute :price_range, :as => :priceRange # i.e. "$$$"
276
+ # for restaurant only only
277
+ attribute :menu
278
+ attribute :reservations, :as => :acceptsReservations # Either Yes/No, or a URL at which reservations can be made.
279
+ attribute :cuisine, :as => :servesCuisine
280
+
281
+ type :vendor, :as => :AnimalShelter
282
+ type :vendor, :as => :AutomotiveBusiness do
283
+ type :vendor, :as => :AutoBodyShop
284
+ type :vendor, :as => :AutoDealer
285
+ type :vendor, :as => :AutoPartsStore
286
+ type :vendor, :as => :AutoRental
287
+ type :vendor, :as => :AutoRepair
288
+ type :vendor, :as => :AutoWash
289
+ type :vendor, :as => :GasStation
290
+ type :vendor, :as => :MotorcycleDealer
291
+ type :vendor, :as => :MotorcycleRepair
292
+ end
293
+ type :vendor, :as => :ChildCare
294
+ type :vendor, :as => :DryCleaningOrLaundry
295
+ type :vendor, :as => :EmergencyService do
296
+ type :vendor, :as => :FireStation
297
+ type :vendor, :as => :Hospital
298
+ type :vendor, :as => :PoliceStation
299
+ end
300
+ type :vendor, :as => :EmploymentAgency
301
+ type :vendor, :as => :EntertainmentBusiness
302
+ type :vendor, :as => :FinancialService
303
+ type :vendor, :as => :FoodEstablishment
304
+ type :vendor, :as => :GovernmentOffice
305
+ type :vendor, :as => :HealthAndBeautyBusiness
306
+ type :vendor, :as => :HomeAndConstructionBusiness
307
+ type :vendor, :as => :InternetCafe
308
+ type :vendor, :as => :Library
309
+ type :vendor, :as => :LodgingBusiness
310
+ type :vendor, :as => :MedicalOrganization
311
+ type :vendor, :as => :ProfessionalService
312
+ type :vendor, :as => :RadioStation
313
+ type :vendor, :as => :RealEstateAgent
314
+ type :vendor, :as => :RecyclingCenter
315
+ type :vendor, :as => :SelfStorage
316
+ type :vendor, :as => :ShoppingCenter
317
+ type :vendor, :as => :SportsActivityLocation
318
+ type :vendor, :as => :Store
319
+ type :vendor, :as => :TelevisionStation
320
+ type :vendor, :as => :TouristInformationCenter
321
+ type :vendor, :as => :TravelAgency
322
+ end
323
+
324
+ type :ngo, :as => :NGO
325
+ type :performing_group, :as => :PerformingGroup
326
+ type :sports_team, :as => :SportsTeam
327
+ end
328
+
329
+ type :person, :as => :Person do
330
+ # addresses
331
+ attribute :address, :type => :address
332
+ attribute :home_address, :as => :homeLocation, :type => :place
333
+ attribute :work_address, :as => :workLocation, :type => :place
334
+
335
+ # organizations
336
+ attribute :organization, :type => :organization
337
+ attribute :education, :type => :organization, :source => :education
338
+ attribute :membership, :type => :organization
339
+ attribute :company, :type => :organization, :as => :worksFor
340
+
341
+ # events
342
+ attribute :performer_in, :type => :event, :as => :performerIn
343
+
344
+ # dates
345
+ attribute :born_on, :type => :date, :as => :birthDate
346
+ attribute :died_on, :type => :date, :as => :deathDate
347
+
348
+ # relationships
349
+ attribute :children, :type => :person
350
+ attribute :parents, :type => :person
351
+ attribute :siblings, :type => :person
352
+ attribute :spouse, :type => :person
353
+ attribute :relationship, :type => :person, :as => :relatedTo
354
+ attribute :colleagues, :type => :person
355
+ # unidirectional
356
+ attribute :follows, :type => :person
357
+ # bidirectional
358
+ attribute :knows, :type => :person
359
+
360
+ # info
361
+ attribute :contact_info, :type => :contact, :as => :contactPoints
362
+ attribute :email
363
+ attribute :phone, :as => :telephone
364
+ attribute :fax, :as => :faxNumber
365
+ attribute :gender
366
+ attribute :interaction_count, :as => :interactionCount
367
+ attribute :job_title, :as => :jobTitle
368
+ attribute :nationality, :type => :place, :source => :country
369
+ end
370
+
371
+ type :place, :as => :Place do
372
+ attribute :address, :type => :address
373
+ attribute :rating, :type => :rating, :as => :aggregateRating
374
+ attribute :surrounding, :type => :place, :as => :containedIn
375
+ attribute :event, :type => :event, :as => :events
376
+ attribute :fax, :as => :faxNumber
377
+ attribute :coordinates, :type => :coordinates, :as => :geo
378
+ attribute :interaction_count, :as => :interactionCount
379
+ attribute :map, :as => :maps
380
+ attribute :image, :type => :image, :as => :photos
381
+ attribute :review, :type => :review, :as => :reviews
382
+ attribute :phone, :as => :telephone
383
+
384
+ type :place, :as => :AdministrativeArea do
385
+ type :place, :as => :City
386
+ type :place, :as => :Country
387
+ type :place, :as => :State
388
+ end
389
+
390
+ type :place, :as => :LandmarksOrHistoricalBuildings
391
+ type :place, :as => :TouristAttraction
392
+
393
+ type :place, :as => :CivicStructure do
394
+ attribute :hours, :as => :openingHours
395
+
396
+ type :place, :as => :Airport
397
+ type :place, :as => :Aquarium
398
+ type :place, :as => :Beach
399
+ type :place, :as => :BusStation
400
+ type :place, :as => :BusStop
401
+ type :place, :as => :Campground
402
+ type :place, :as => :Cemetery
403
+ type :place, :as => :Crematorium
404
+ type :place, :as => :EventVenue
405
+ type :place, :as => :FireStation
406
+ type :place, :as => :GovernmentBuilding
407
+ type :place, :as => :Hospital
408
+ type :place, :as => :MovieTheater
409
+ type :place, :as => :Museum
410
+ type :place, :as => :MusicVenue
411
+ type :place, :as => :Park
412
+ type :place, :as => :ParkingFacility
413
+ type :place, :as => :PerformingArtsTheater
414
+ type :place, :as => :PlaceOfWorship
415
+ type :place, :as => :Playground
416
+ type :place, :as => :PoliceStation
417
+ type :place, :as => :RVPark
418
+ type :place, :as => :StadiumOrArena
419
+ type :place, :as => :SubwayStation
420
+ type :place, :as => :TaxiStand
421
+ type :place, :as => :TrainStation
422
+ type :place, :as => :Zoo
423
+ end
424
+
425
+ type :place, :as => :Landform do
426
+ type :place, :as => :BodyOfWater
427
+ type :place, :as => :Continent
428
+ type :place, :as => :Mountain
429
+ type :place, :as => :Volcano
430
+ end
431
+
432
+ type :place, :as => :Residence do
433
+ type :place, :as => :ApartmentComplex
434
+ type :place, :as => :GatedResidenceCommunity
435
+ type :place, :as => :SingleFamilyResidence
436
+ end
437
+ end
438
+
439
+ type :product, :as => :Product do
440
+ attribute :rating, :as => :aggregateRating, :type => :rating
441
+ attribute :brand, :type => :organization
442
+ attribute :manufacturer, :type => :organization
443
+ attribute :model
444
+ attribute :offer, :as => :offers, :type => :offer
445
+ attribute :uid, :as => :productID
446
+ attribute :review, :as => :reviews, :type => :review
447
+ end
448
+ end
449
+ end
450
+ end