Dropping the pretense one thing is so different from another, the elioWay
Thing
.ItemList.itemListElement
property of the thing.
Thing
can be repeated inside the
SchemaOrg subclass.
All TEW data is modelled on
SchemaOrg metadata. Schema models
self-describe an increasingly large number of semantically rich
"entities" - such as School
, Farm
,
Business
, GeoCoordinate
, Place
,
BuddistTemple
, MedicalInstrument
,
Person
- with 100s more.
SchemaOrg is hierarchical, with the top level
Thing
containing a small number of properties.
We call every record a "thing" in TEW because it is modelled on
SchemaOrg's top level metaclass Thing
.
This might well be the smallest thing
possible:
{ identifier: 1 }
If your data is stored with SchemaOrg vocabulary, it can be rendered with SchemaOrg vocabulary. You get SEO out of the box TEW - you won't even need to think about it.
Here are the only properties of a Thing
.
https://schema.org/Thing:
{
"additionalType": "CatzMeowBuddistTemple",
"alternateName": "Catz Meow, **the elioWay**",
"description": "<p>The Catz Meow Temple has interesting features we have listed.</p>",
"disambiguatingDescription": "Thailand,Buddism,Temple,Tourism",
"identifier": "CatzMeowTempleLaemSing",
"image": "selfie-catzmeow-christmas99,jpg",
"mainEntityOfPage": "BuddistTemple",
"name": "Catz Meow Temple",
"potentialAction": "visit",
"sameAs": "being there",
"subjectOf": "thailand",
"url": "https://www.google.com/maps/place/Wat+Ko+Maew/@12.4633965,102.091651,15z/",
}
TEW is commandeering these properties and adding an additional application meaning to them:
additionalType
mainEntityOfPage
.identifier
mainEntityOfPage
name
potentialAction
subjectOf
url
We have no planned use for the other core property names... right now. Reserved for future.
An entire app could easily be crafted with just the
Thing
type alone. But you should always choose the best type
for your app, and each thing listed. TEW apps work best when the full
descriptive power of SchemaOrg is utilized.
To "schemify" the record (i.e. to add, to it, a specific type from SchemaOrg) you add the name of the subtype(s) as a key to the main object.
This would be an https://schema.org/Action thing.
Thing > Action
{
"identifier": "007",
"mainEntityOfPage": "Action",
<moreThingProperties>,
"Action": {
"actionStatus": "PotentialActionStatus",
"agent": "007",
"error": "leaving 007 unattended",
"instrument": "giant laser missile",
"location": "moon base",
"object": "evil villian",
"participant": "a white cat",
"result": "world saved",
"startTime": "00:10",
"endTime": "00:00",
"target": "00:01"
}
}
Or a https://schema.org/Restaurant
Thing > Organization > LocalBusiness > FoodEstablishment
> Restaurant
Thing > Place > LocalBusiness > FoodEstablishment >
Restaurant
{
"identifier": "JamaicaInn",
"mainEntityOfPage": "Restaurant",
<moreThingProperties>,
"Restaurant": {},
"Place": {
"latitude": "",
"longitude": "",
"tourBookingPage": "",
<morePlaceProperties>
},
"Organization": {
"address": "",
"faxNumber": "",
"founder": "",
"foundingDate": "",
<moreOrganizationProperties>
},
"LocalBusiness": {
"currenciesAccepted": "",
"openingHours": "",
<moreLocalBusinessProperties>
},
"FoodEstablishment": {
"acceptsReservations": "",
"hasMenu": "",
"menu": "",
<moreFoodEstablishmentProperties>
}
}
The Restaurant
entry has no properties itself. This
highlights the importance of using Schema in providing a
Semantic layer. JUst the presense of the
Restaurant
key is significant data.
In TEW there is no reason why we couldn't stretch Schema a bit by
adding subtypes not officially in SchemaOrg hierarchy for
the mainEntityOfPage
. It would not spoil SEO.
In this example, although we are modelling a Restaurant
, we
can add the
https://schema.org/Book and
https://schema.org/Movie aspects
relevant to the subject (and they both inherit from
https://schema.org/CreativeWork).
{
"identifier": "JamaicaInn",
"mainEntityOfPage": "Restaurant",
<moreThingProperties>,
"Restaurant": {},
"Place": {
<placeProperties>
},
"Organization": {
<organizationProperties>
},
"LocalBusiness": {
<localBusinessProperties>
},
"FoodEstablishment": {
<foodEstablishmentProperties>
},
CreativeWork: {
author: "Daphne du Maurier",
<moreCreativeWorkProperties>
}
Book: { },
Movie: {
"director": "Alfred Hitchcock"
}
}
And since we are commandeering and reserving core
Thing
properties for application purposes, we will allow core
Thing
properties inside sub types, like this:
{
"identifier": "Jamaica_Inn",
"name": "Jamaica Inn",
"mainEntityOfPage": "Restaurant",
<moreThingProperties>,
"Restaurant": {
name: "Jamaica Inn Restaurant"
},
"Place": {
"name": "Jamaica Inn Tourist Attraction",
<placeProperties>
},
"Organization": {
"name": "Jamaica Inn Protectorate",
<organizationProperties>
},
"LocalBusiness": {
"name": "Jamaica Inn Gift Shop",
<localBusinessProperties>
},
"FoodEstablishment": {
"name": "Jamade A Snack",
<foodEstablishmentProperties>
},
CreativeWork: {
"name": "Jamaica Inn",
"author": "Daphne du Maurier",
<moreCreativeWorkProperties>
},
Book: { },
Movie: {
"director": "Alfred Hitchcock"
}
}
This works great. Since subtypes inherit Thing properties, it will
actually be useful to be able to give each subtype a name, or
disambiguatingDescription. In the above example the
Restaurent
side of "Jamaica_Inn" can have a
different name from the Movie
angle, but
"Jamaica_Inn" can only have 1 of each "side".
With TEW, iteration is a design feature, not merely a programming device. Any property in a thing can be a thing itself, which can be engaged with properties that have engagable things in properties and lists
{
"identifier": "Jamaica_Inn",
"name": "Jamaica Inn",
"mainEntityOfPage": "CreativeWork",
"CreativeWork": {
"name": "Jamaica Inn",
"author": {
"identifier": "Daphne_du_Maurier",
"name": "Daphne du Maurier",
"mainEntityOfPage": "Person",
ItemList: {
itemlistElement: [
{identifier: "Rebecca"},
{identifier: "TheBirds"},
{identifier: "Jamaica_Inn"}
]
}
}
}
}
Because TEW is backed by Schema, we can overlay Things with the meta vocabulary backing it:
{
"additionalType": {
"type": "URL"
},
"description": {
"type": "Text"
},
"image": {
"type": "URL"
},
"mainEntityOfPage": {
"type": "URL"
},
"name": {
"type": "Text"
},
"potentialAction": {
"type": "Text"
},
"sameAs": {
"type": "URL"
},
"subjectOf": {
"type": "Text"
},
"url": {
"type": "URL"
},
"Restaurant": {},
"Place": {
"additionalProperty": {
"type": "Text"
},
"hasDriveThroughService": {
"type": "Boolean"
},
"maximumAttendeeCapacity": {
"type": "Integer"
},
},
"LocalBusiness": {
"branchOf": {
"type": "Organization",
"foreign": true
},
...AND SO ON
}
Not only will these meta packages help automate database generation,
To put the icing on the cake, Schema describes its properties:
...
"Place": {
"additionalProperty": {
"type": "Text",
"comment": "A property-value pair representing an additional characteristics of the entitity, e.g. a product feature or another characteristic for which there is no matching property in schema.org.<br/><br/>\n\nNote: Publishers should be aware that applications designed to use specific schema.org properties (e.g. http://schema.org/width, http://schema.org/color, http://schema.org/gtin13, ...) will typically expect such data to be provided using those properties, rather than using the generic property/value mechanism."
},
"address": {
"type": "Text",
"comment": "Physical address of the item."
},
"aggregateRating": {
"type": "Text",
"comment": "The overall rating, based on a collection of reviews or ratings, of the item."
},
"amenityFeature": {
"type": "Text",
"comment": "An amenity feature (e.g. a characteristic or service) of the Accommodation. This generic property does not make a statement about whether the feature is included in an offer for the main accommodation or available at extra costs."
},
"branchCode": {
"type": "Text",
"comment": "A short textual code (also called \"store code\") that uniquely identifies a place of business. The code is typically assigned by the parentOrganization and used in structured URLs.<br/><br/>\n\nFor example, in the URL http://www.starbucks.co.uk/store-locator/etc/detail/3047 the code \"3047\" is a branchCode for a particular branch."
},
"containedIn": {
"type": "Place",
"foreign": true,
"comment": "The basic containment relation between a place and one that contains it."
},
...
How about getting that as a package to help dynamically build a webform? Except you won't have to... it will already be done for TEW.
And... leaving the most obvious thing until last - if your data is stored with SchemaOrg vocabulary, it can be rendered with SchemaOrg vocabulary - seo by default - you won't even need to think about it baby!
eliothing proposes an opinionated, repeating pattern for dealing with instances of primary records in a database, where each has its own self contained list of records related to it, where each of those could have a self contained list of records related to it, and where each of those could have a self contained list of records related to it...
Load this data in any TEW app, and it will be able to update, summarise, optimize, or otherwise do something its user might find useful in the relationship between the primary engaged thing and the data in its list.
SEO out of the box.