A place to cache linked articles (think custom and personal wayback machine)
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

index.html 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>The Content Management System of my Dreams (part 1) - A little bit of history (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://www.padawan.info/en/2023/02/the-content-management-system-of-my-dreams-part-1-a-little-bit-of-history.html">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>The Content Management System of my Dreams (part 1) - A little bit of history</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://www.padawan.info/en/2023/02/the-content-management-system-of-my-dreams-part-1-a-little-bit-of-history.html" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p><strong>The world needs more static sites but does not need yet another <abbr title="Static Site Generator">SSG</abbr> munching Markdown files.</strong></p>
  71. <p>Each and every time I encounter a new <abbr title="Content Management System">CMS</abbr> I cry and want to design a new one. No wonder why there is a flurry of half-baked “off-the-shelf” CMS and even more custom ones out there.</p>
  72. <p>Most tech people do not understand the sweet spot between designing and editing a web site, its content management, static <i>vs</i> dynamic publishing, and all their users real needs. Or even who are the <em>real</em> users of the end product.</p>
  73. <h3>A little history about a forgotten jewel</h3>
  74. <p>In 2001 — that's 22 years ago, about a bazillion years in web time — a tiny two-people company named Six Apart, announced and published <a href="https://en.wikipedia.org/wiki/Movable_Type">Movable Type</a>. It was a blog engine that, from the start, allowed one to publish any number of blogs, related or not down to their domain names, with a 100% web <abbr title="User Interface">UI</abbr> that allowed designers, contributors, editors and site visitors to do what they each wanted to do.</p>
  75. <p>Designers could create and manage all templates using a browser. The template markup (<abbr title="Movable Type Markup Language">MTML</abbr>) would prevent, by design, obvious security issues by simply not allowing anything outside what it was designed to do: display content — whatever it is, it did not care if it is HTML, PDF, PHP and whatnot — in the site style.<br>It did not prevent one to extend the application logic, using either a scripting language of their choosing, or developing plugins that would expose new MTML tags.<br>It introduced a very powerful concept: the ability to publish anything as files, with a template logic allowing to generate index pages (like the home page), listings (e.g. a page listing blog entries, lists generated through custom rules such as tags, categories, date-based archives etc.), and custom shared templates you could use directly in other templates and computed in-place or just once and included either via an internal cache or via Apache and PHP includes.<br>Cherry on the cake, it included a very smart internal cache system that would allow the designer to tell <abbr title="Movable Type">MT</abbr> exactly when and where to refresh files. This particular ability, which about no CMS gets right 22 years later, would allow MT to publish a blog in 100% static HTML files with visitors comments added on the fly by republishing <em>only the strict minimum of pages</em> (obviously the commented blog post, along with any page impacted by it, like a page displaying the latest comments or their number).</p>
  76. <p>Yes, 22 years ago we had a CMS that would allow dynamic content on a static site. And even if it needed a database for content <em>management</em>, it would not for <em>serving content</em>. You could shut down your database server, the site would continue to work just fine if no new content needed to be published. If you had to face a spam attack throught comments, you could just disable one file and your site would still work, just without new comments while waiting for the wave to pass.</p>
  77. <p></p>
  78. <p>You know what? <a href="http://www.movabletype.com">Movable Type</a> is still alive and kicking today. Albeit in Japanese and developed by a company that used to care about editors outside Japan.<br>I have been using it from day one of this blog (né Year II before <abbr title="Loïc Le Meur, coucou Loïc , long time no see!">LLM</abbr>). I have tried a few times to play with a new CMS only to go back to MT.<br>I have built several sites, <a href="https://www.lefigaro.fr/blogs">one of them</a> growing over a million PV per day on a single small web server that did not need any upgrade for years, <a href="https://www.paris-web.fr">another one</a> that has quite a complex set of content and sustained years of attempts by WordPress lovers to replace it, only for them to come to love MT at the end, each and every time.</p>
  79. </article>
  80. <hr>
  81. <footer>
  82. <p>
  83. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  84. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  85. </svg> Accueil</a> •
  86. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  87. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  88. </svg> Suivre</a> •
  89. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  90. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  91. </svg> Pro</a> •
  92. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  93. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  94. </svg> Email</a> •
  95. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  96. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  97. </svg> Légal</abbr>
  98. </p>
  99. <template id="theme-selector">
  100. <form>
  101. <fieldset>
  102. <legend><svg class="icon icon-brightness-contrast">
  103. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  104. </svg> Thème</legend>
  105. <label>
  106. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  107. </label>
  108. <label>
  109. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  110. </label>
  111. <label>
  112. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  113. </label>
  114. </fieldset>
  115. </form>
  116. </template>
  117. </footer>
  118. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  119. <script>
  120. function loadThemeForm(templateName) {
  121. const themeSelectorTemplate = document.querySelector(templateName)
  122. const form = themeSelectorTemplate.content.firstElementChild
  123. themeSelectorTemplate.replaceWith(form)
  124. form.addEventListener('change', (e) => {
  125. const chosenColorScheme = e.target.value
  126. localStorage.setItem('theme', chosenColorScheme)
  127. toggleTheme(chosenColorScheme)
  128. })
  129. const selectedTheme = localStorage.getItem('theme')
  130. if (selectedTheme && selectedTheme !== 'undefined') {
  131. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  132. }
  133. }
  134. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  135. window.addEventListener('load', () => {
  136. let hasDarkRules = false
  137. for (const styleSheet of Array.from(document.styleSheets)) {
  138. let mediaRules = []
  139. for (const cssRule of styleSheet.cssRules) {
  140. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  141. continue
  142. }
  143. // WARNING: Safari does not have/supports `conditionText`.
  144. if (cssRule.conditionText) {
  145. if (cssRule.conditionText !== prefersColorSchemeDark) {
  146. continue
  147. }
  148. } else {
  149. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  150. continue
  151. }
  152. }
  153. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  154. }
  155. // WARNING: do not try to insert a Rule to a styleSheet you are
  156. // currently iterating on, otherwise the browser will be stuck
  157. // in a infinite loop…
  158. for (const mediaRule of mediaRules) {
  159. styleSheet.insertRule(mediaRule.cssText)
  160. hasDarkRules = true
  161. }
  162. }
  163. if (hasDarkRules) {
  164. loadThemeForm('#theme-selector')
  165. }
  166. })
  167. </script>
  168. </body>
  169. </html>