When a CMS is not enough

When a CMS is not enough

22725c2d3eb331146549bf0d5d3c050c?s=128

stefan judis

October 29, 2018
Tweet

Transcript

  1. When a CMS is not enough Tales from a content

    infrastructure @stefanjudis
  2. Stefan Judis Frontend Developer, Occasional Teacher, Meetup Organizer ❤ Open

    Source, Performance and Accessibility ❤ @stefanjudis
  3. Content management like it used to be

  4. We are so slow!

  5. Everything's broken!

  6. We want to have a site!

  7. We want to have a site and an app!

  8. We want to have a site and two apps!

  9. We want to have two sites and two apps!

  10. We want our content to be everywhere!

  11. That's not what most of the systems are built for

  12. COMMON CMS PROBLEMS PAGE-CENTRIC MODEL MONOLYTHIC SOLUTION SLOW ITERATIONS

  13. COMMON CMS PROBLEMS PAGE-CENTRIC MODEL MONOLYTHIC SOLUTION SLOW ITERATIONS You

    can build your own solution, but...
  14. I don't want to do that!

  15. I don't want to do that! I don't have time

    for that!
  16. Building businesses has become software.

  17. Building brands has become software.

  18. Building revenue has become software.

  19. Building market share has become software.

  20. Being successful means building great software.

  21. You don't want to waste time!

  22. None
  23. App development today 50% use 2-5 APIs 9% use 25+

    APIs Global Development Survey Vol. 1 © 2017 Evans Data
  24. THERE'S AN API FOR EVERYTHING

  25. Communication And the list goes on and on... Specialized Services

    Payment Search
  26. Platform as a Service (PaaS) Specialized Services on top of

    PaaS and IaaS Infrastructure as a Service (IaaS)
  27. Should we rethink the approach to content management, too?

  28. And not reinvent the wheel all the time...

  29. ... to ship products with great content instead!

  30. Platform as a Service (PaaS) Specialized Services on top of

    PaaS and IaaS Infrastructure as a Service (IaaS)
  31. Platform as a Service (PaaS) Specialized Services on top of

    PaaS and IaaS Infrastructure as a Service (IaaS)
  32. Sascha Konietzke Contentful Content Infrastructure is architected to deliver content

    to any channel or digital product, and allows frequent adjustments and iteration, by fitting into modern agile development practices.
  33. CROSS-PLATFORM DELIVERY CHANGING REQUIREMENTS MODERN STACK
 DEVELOPMENT CONTENT INFRASTRUCTURE

  34. PLATFORM PORTABILITY

  35. The world speaks JSON

  36. A JSON API { "sys": { "contentType": { "sys": {

    "id": "page" } } }, "fields": { "title": "Page", "body"; "This is an article about ..." } }
  37. A JSON API

  38. SCALABLE {} {} {} {} {} {} {} {} {}

    {} {} {} {} {} {}
  39. SCALABLE {} {} {} {} {} {} {} {} {}

    {} {} {} {} {} {} CONTENT DELIVERED BY FAST CDNs
  40. API at Scale !== Content at Scale

  41. CONTENT AT SCALE STRUCTURED CONTENT SPEEDY DEVELOPMENT GOOD EDITING EXPERIENCE

  42. STRUCTURED CONTENT GET JSON

  43. STRUCTURED CONTENT GET JSON ? ? ? GET JSON

  44. STRUCTURED CONTENT GET JSON ? ? ? GET JSON Break

    down your content into reusable components!
  45. STRUCTURED CONTENT GET JSON ? ? ? GET JSON

  46. STRUCTURED CONTENT GET JSON GET JSON

  47. STRUCTURED CONTENT GET JSON GET JSON Content has to become

    a structured graph
  48. Title Title Artist Artist Name Image Sigh no more Babel

    Mumford & Sons Mumford & Sons Mumford & Sons
  49. Title Title Artist Artist Name Image Sigh no more Babel

    Mumford & Sons & Me Mumford & Sons & Me Mumford & Sons & Me
  50. Title Title Artist Artist Name Image Sigh no more Babel

    Mumford & Sons & Me Mumford & Sons & Me Mumford & Sons & Me
  51. Title Title Artist Artist Name Image Sigh no more Babel

    Mumford & Sons & Me Mumford & Sons & Me Mumford & Sons & Me
  52. Title Title Artist Artist Name Image Sigh no more Babel

    Mumford & Sons & Me Mumford & Sons & Me Mumford & Sons & Me Every node of the graph has to be accessible (together & separate)
  53. Content modelling is an art!

  54. HOW TO EDIT THE CONTENT?

  55. Name Image Mumford & Sons Description Mumford & Sons are

    a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass).
  56. WYSIWYG

  57. None
  58. None
  59. Content vs. Look DON'T BREAK SEPARATION OF CONCERNS

  60. Html

  61. Html

  62. Html Whenever you put HTML in your content you're breaking

    portability!
  63. DISADVANTAGES OF WYSIWYG Too flexible 01 Mixes content and looks

    02 03 Too easy to mess up 04 HTML is the goal
  64. You want to limit the user!

  65. Markdown

  66. # Heading ## Sub-heading Text attributes _italic_, **bold**, `monospace`. Bullet

    list: * apples * oranges * pears A [link](http://example.com). ![Image](duck.png) Heading Sub-heading Text attributes italic, bold, monospace. Bullet list: - apple - oranges - pears A link.
  67. Inline <abbr title="Hypertext Markup Language">HTML</abbr> is supported. Inline HTML is

    supported.
  68. # Heading And a paragraph... ![Image](duck.png)

  69. # Heading And a paragraph... ![Image](duck.png) And a paragraph... ![Image](duck.png)

    And a paragraph...
  70. # Heading And a paragraph... ??? And a paragraph... ![Image](duck.png)

    And a paragraph...
  71. # Heading And a paragraph... ??? And a paragraph... ???

    And a paragraph...
  72. # Heading And a paragraph... ??? ??? And a paragraph...

    ??? And a paragraph...
  73. # Heading And a paragraph... ??? ??? And a paragraph...

    ??? ??? !!! ??? Tooltip!
  74. ADVANTAGES OF MARKDOWN Limited functionality 01 Focuses on semantics 02

    03 Easy to grasp
  75. DISADVANTAGES OF MARKDOWN Limited functionality 01 Not powerful enough 02

    03 Editors don't like it 04 HTML is "allowed"
  76. THE BIGGEST PROBLEM A [link](http://example.com).

  77. THE BIGGEST PROBLEM Name Mumford & Sons Name Marcus Mumford

    Slug marcus-mumford Description Mumford & Sons are a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass). [Markus Mumford](http://.../artist/marcus-mumford)
  78. THE BIGGEST PROBLEM Name Mumford & Sons Name Marcus Mumford

    Slug marcus-mumford-jr Description Mumford & Sons are a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass). [Markus Mumford](https://.../artist/marcus-mumford-jr) ?
  79. THE BIGGEST PROBLEM Name Mumford & Sons Name Marcus Mumford

    Slug marcus-mumford-jr Description Mumford & Sons are a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass). [Markus Mumford](https://.../artist/marcus-mumford-jr) ? References are not possible in Markdown!
  80. RICH TEXT

  81. Rich text JSON Name Mumford & Sons Description Mumford &

    Sons are a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass). { "data": {}, "content": [ ], "nodeType": "document" }
  82. Rich text JSON Name Mumford & Sons Description Mumford &

    Sons are a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass). { "data": {}, "content": [ { "data": {}, "content": [ ], "nodeType": "paragraph" } ], "nodeType": "document" }
  83. Rich text JSON Name Mumford & Sons Description Mumford &

    Sons are a British band formed in 2007. The band consists of Marcus Mumford (lead vocals, electric guitar, acoustic guitar, drums), Ben Lovett (vocals, keyboard, piano, synthesizer), Winston Marshall (vocals, electric guitar, banjo) and Ted Dwane (vocals, bass guitar, double bass). { "data": {}, "content": [ { "data": {}, "content": [ { "data": {}, "marks": [], "value": "Mumford & Sons ...", "nodeType": "text" } ], "nodeType": "paragraph" } ], "nodeType": "document" }
  84. Rich text JSON const COMPONENT_RENDER_MAP = { paragraph: item =>

    <p>{item.content.map(item => renderItem(item))}</p>, "heading-1": item => <h1>{item.content.map(item => renderItem(item))}</h1>, "heading-2": item => <h2>{item.content.map(item => renderItem(item))}</h2>, // ... }; export const renderItem = item => { return COMPONENT_RENDER_MAP[item.nodeType](item); };
  85. Rich text JSON

  86. A different editing experience

  87. It's pure structured content A different editing experience

  88. Name Image Mumford & Sons Name Image Mumford & Sons

    & Me JSON ???
  89. You have to provide an editorial preview mechanism!

  90. Required APIs Content Delivery API Content Preview API staging production

  91. Name Image Mumford & Sons Name Image Mumford & Sons

    & Me JSON ???
  92. Name Image Mumford & Sons Name Image Mumford & Sons

    & Me JSON JSON DELIVERY API PREVIEW API
  93. None
  94. YOUR EDITORS HAVE TO BE HAPPY (AND SAFE)

  95. But how to get started?

  96. START SMALL. ITERATE!

  97. None
  98. Name Date Contentful Certification Workshop Description Get your Contentful Certification.

    Join our one-day event, packed with workshops, practice sessions, and only a few, short presentations. October 29th, 2018 City Berlin Country Germany
  99. Name Date Contentful Certification Workshop Description Get your Contentful Certification.

    Join our one-day event, packed with workshops, practice sessions, and only a few, short presentations. October 29th, 2018 City Berlin Country Germany Setting up your content infrastructure will take you two minutes!
  100. Name Date Contentful Certification Workshop ... Name Date JAMstack Conf

    ... Name Mumford & Sons Name Slug Blog page blog Name Date How to do Contentful? ... Name Date O'reilly Software architecture October 29th Name Lucy Rose
  101. Name Date Contentful Certification Workshop ... Name Date JAMstack Conf

    ... Name Mumford & Sons Name Slug Blog page blog Name Date How to do Contentful? ... Name Date O'reilly Software architecture October 29th Name Lucy Rose At some point it will be time to refactor
  102. NOBODY(!) GETS CONTENT MODELLING RIGHT THE FIRST TIME...

  103. Traditional CMS flow

  104. Traditional CMS flow How do you do this with an

    API?
  105. Content infrastructure flow MIGRATION SCRIPTS SANDBOX ENVIRONMENTS

  106. Content infrastructure flow

  107. CREATE MULTIPLE VERSIONS OF YOUR CONTENT CHANGE/TEST THEM IN ISOLATION

  108. cdn.contentful.com/spaces/{space_id}/entries const contentful = require('contentful'); const client = contentful.createClient({ space:

    '<space_id>', accessToken: '<content_delivery_api_key>' }); client.getEntries();
  109. cdn.contentful.com/spaces/{space_id}/environments/{environment_id}/entries const contentful = require('contentful'); const client = contentful.createClient({ space:

    '<space_id>', environment: '<environment_id>', accessToken: '<content_delivery_api_key>' }); client.getEntries();
  110. COPIED Content types Entries Assets Locales UI-extensions Saved views SHARED

    Users & space memberships Roles & permissions API keys Web hooks
  111. Required APIs Content Delivery API Content Preview API staging production

    Content Management API automation
  112. None
  113. Make it as easy as possible

  114. github.com/contentful/contentful-migration

  115. MIGRATION CLI CONTENT TYPE OPERATIONS Create a content type 01

    02 03 04 05 Delete a content type Edit a content type Create/edit/delete fields Change a field ID
  116. Add new field module.exports = function (migration) { const tilPost

    = migration.editContentType('tilPost') }
  117. Add new field module.exports = function (migration) { const tilPost

    = migration.editContentType('tilPost') tilPost.createField( 'tags', { name: 'Tags', type: 'Array', items: { type: 'Symbol' } } ); }
  118. None
  119. Transform an entry in place 01 02 Derive an entry

    from another MIGRATION CLI CONTENT TRANSFORMATIONS
  120. None
  121. None
  122. DERIVE ENTRIES AND LINK Name Fronttrends 2017 City Warsaw Country

    Poland Name Fronttrends 2018 City Warsaw Country Poland
  123. DERIVE ENTRIES AND LINK Name Fronttrends 2017 City Warsaw Country

    Poland Name Fronttrends 2018 City Warsaw Country Poland Name Fronttrends City Warsaw Country Poland
  124. DERIVE ENTRIES AND LINK Name Fronttrends 2017 Conference Name Fronttrends

    2018 Conference Name Fronttrends City Warsaw Country Poland Fronttrends Fronttrends
  125. module.exports = function (migration) { const conference = migration.createContentType('conference') .name('Conference/Meetup')

    .displayField('name') conference.createField('name').type('Symbol').required(true).name('Conference/Meetup name') conference.createField('country').type('Symbol').required(true).name('Country Code') conference.createField('city').type('Symbol').required(true).name('City') const event = migration.editContentType('event') event.createField('conference') .name('Conference') .type('Link') .linkType('Entry') .validations([ { "linkContentType": ['conference'] } ]) migration.deriveLinkedEntries({ contentType: 'event', from: ['name', 'country', 'city'], toReferenceField: 'conference', derivedContentType: 'conference', derivedFields: ['name', 'country', 'city'], identityKey: async (from) => { return from.name['en-US'] // remove year .replace(/\s(\d{2,4}|#\d+)/g, '') // clear spaces .replace(/\s/g, '-') // clear "weird characters" .replace(/(,|\/|\\|:|\.|\(|\))/g, '') .toLowerCase() }, deriveEntryForLocale: async (inputFields, locale) => { return { name: inputFields.name[locale].replace(/\s(\d{2,4}|#\d+)/g, ''), country: inputFields.country[locale] || 'N/A', city: inputFields.city[locale] || 'N/A' } } }) event.moveField('conference').afterField('name') event.deleteField('country') event.deleteField('city') } LOC 48 REQUESTS 382 ENTRIES CREATED 88 ENTRIES UPDATED 96
  126. MIGRATION CLI ADVANTAGES Repeatable 01 02 03 04 Can be

    kept in VC Includes sanity checks Perfect for CI
  127. CMS as Code (automation like a boss)

  128. FEATURE SANDBOXES

  129. FEATURE SANDBOXES ENVIRONMENT SANDBOXES

  130. ENVIRONMENT SANDBOXES FEATURE SANDBOXES CI SANDBOXES

  131. Deluan Quintao ThoughtWorks We ran 500 migrations this year. Our

    content structure is tightly coupled to the code changes we make.
  132. None
  133. www.contentful.com/blog/2018/09/13/content-model-changes-scale-telus-cms-as-code/

  134. Automate everything

  135. None
  136. Required APIs Content Delivery API Content Preview API staging production

    Content Management API automation Images API assets
  137. https: //images.ctfassets.net/ .../public-transport.jpg 3.2MB

  138. https: //images.ctfassets.net/ .../public-transport.png?w=800 60KB

  139. https: //images.ctfassets.net/ .../public-transport.png?w=800&fm=webp 30KB

  140. https: //images.ctfassets.net/ .../public-transport.png?w=800&fm=jpg&q=10 17KB

  141. https: //images.ctfassets.net/ .../public-transport.png?w=800&h=200&fit=crop

  142. Use the right tools for the job

  143. ... and connect the all the dots

  144. Phil Hawksworth Netlify Webhooks are the API of the web

  145. Platform as a Service (PaaS) Specialized Services on top of

    PaaS and IaaS Infrastructure as a Service (IaaS)
  146. POST Headers: content-type: application/json Body: { sys: { ...}, fields:

    { ...} } ⛔
  147. POST Headers: content-type: application/json X-Algolia-Application-Id: xxx X-Algolia-API-key: xxx Body: {

    sys: { ...}, fields: { ...} } ✅
  148. POST Headers: content-type: application/json X-Algolia-Application-Id: xxx X-Algolia-API-key: xxx Body: {

    sys: { ...}, fields: { ...} }
  149. POST Headers: content-type: application/json X-Algolia-Application-Id: xxx X-Algolia-API-key: xxx Body: {

    sys: { ...}, fields: { ...} } contentType.sys.id === 'post'
  150. POST ✅ Headers: content-type: application/json X-Algolia-Application-Id: xxx X-Algolia-API-key Body: {

    title: 'hello world', content: ' ...' } contentType.sys.id === 'post' + custom payload
  151. POST ✅ Headers: content-type: application/json X-Algolia-Application-Id: xxx X-Algolia-API-key Body: {

    title: 'hello world', content: ' ...' } contentType.sys.id === 'post' + custom payload
  152. ...

  153. ADJUSTABLE SCALABLE WEBHOOKS FLEXIBLE TRANSPARENT

  154. Integrate other services

  155. ...

  156. ... ...

  157. UI Extensions <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://contentful.github.io/.../cf-extension.css"> <script

    src="https://unpkg.com/contentful-ui-extensions-sdk@3"></script> </head> <body> </body> </html>
  158. UI Extensions <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://contentful.github.io/.../cf-extension.css"> <script

    src="https://unpkg.com/contentful-ui-extensions-sdk@3"></script> </head> <body> <script> window.contentfulExtension.init(function ({ entry, field, window, parameters }) { // connect to other APIs // add your own logic and appearance // ... }); </script> </body> </html>
  159. UI Extensions

  160. BE FRIENDS WITH OTHER VENDORS!

  161. None
  162. A rich ecosystem is indispensable

  163. Technology is not the only factor to success

  164. Talent decides about failure and success

  165. Henrik Joreteg You're shaping tomorrow's job market based on the

    technology choices you make today.
  166. The industry has a pipeline problem...

  167. 167 1,6 % 3,4 % 5,5 % 6,5 % 7,4

    % 10 % 14 % 16 % 17 % 18 % HOW DO DEVELOPERS ASSESS POTENTIAL JOBS? insights.stackoverflow.com/survey/2018/#technology-and-society 1 1. Compensation and Benefits 2 2. Language, Frameworks and Technology 3 3. Professional Development
  168. 168 1,6 % 3,4 % 5,5 % 6,5 % 7,4

    % 10 % 14 % 16 % 17 % 18 % HOW DO DEVELOPERS ASSESS POTENTIAL JOBS? insights.stackoverflow.com/survey/2018/#technology-and-society 1 1. Compensation and Benefits 2 2. Language, Frameworks and Technology 3 3. Professional Development
  169. 169 1,6 % 3,4 % 5,5 % 6,5 % 7,4

    % 10 % 14 % 16 % 17 % 18 % HOW DO DEVELOPERS ASSESS POTENTIAL JOBS? insights.stackoverflow.com/survey/2018/#technology-and-society 1 1. Compensation and Benefits 2 2. Language, Frameworks and Technology 3 3. Professional Development Your CMS is part of that decision!
  170. DEVELOPERS LOVE NEW TOOLS!

  171. None
  172. “ Backend Engineer: Hmm. So you’re saying this “GraphQL” will

    allow any web or native engineer to arbitrarily query basically any field in any backend service, recursively, however they want, without any backend engineers involved? Frontend Engineer: Yeah, right? It’s amazing! […silence…] medium.com/airbnb-engineering/reconciling-graphql-and-thrift-at-airbnb-a97e8d290712
  173. None
  174. One request per resource

  175. None
  176. POST query { course (id: "1toEOumnkEksWakieoeC6M") { fields { title

    slug skillLevel } } ... } { "data": { "course": { "fields": { "title": "Hello Contentful", "slug": "hello-contentful", "skillLevel": "beginner" } } ... } }
  177. POST query { course (id: "1toEOumnkEksWakieoeC6M") { fields { title

    slug skillLevel } } ... } { "data": { "course": { "fields": { "title": "Hello Contentful", "slug": "hello-contentful", "skillLevel": "beginner" } } ... } } One request for everything
  178. None
  179. github.com/prisma/graphql-playground

  180. Who uses GraphQL?

  181. GraphQL will change the way we work completely.

  182. "Modern Stack Website" (I'm biased)

  183. More and more logic went into the client

  184. SSG Build tool content & templates CSS & JavaScript

  185. SSG Build tool content & templates CSS & JavaScript

  186. SSG Build tool content & templates CSS & JavaScript Constant

    context switch
  187. SSG Build tool content & templates CSS & JavaScript

  188. SSG Build tool content & templates CSS & JavaScript

  189. SSG Build tool content & templates CSS & JavaScript API

    data has to be written to disk
  190. SSG Build tool content & templates CSS & JavaScript

  191. None
  192. Universal JavaScript Apps (completely JS driven)

  193. Rich ecosystem Unified code base Cutting edge technologies Developer tooling

    Static HTML MODERN STACK WEBSITE
  194. Modern Stack Website

  195. Frontend technology today is built to consume APIs. Modern Stack

    Website
  196. Modern Stack Website

  197. Modern Stack Website

  198. Modern Stack Website

  199. Modern Stack Website Scalable, flexible and cheap!

  200. My advice to content management:

  201. Content has to be consumable!

  202. Content has to be flexible!

  203. Content has to be ready for iterations!

  204. Let's not reinvent the wheel all the time...

  205. ...let's ship great products with great content!

  206. Thanks. @stefanjudis Slides ctfl.io/when-a-cms-is-not-enough