惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
O
OpenAI News
N
News and Events Feed by Topic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
Google Online Security Blog
Google Online Security Blog
云风的 BLOG
云风的 BLOG
N
News | PayPal Newsroom
H
Hacker News: Front Page
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Last Watchdog
The Last Watchdog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Heimdal Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Schneier on Security
宝玉的分享
宝玉的分享
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
Microsoft Security Blog
Microsoft Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
GbyAI
GbyAI
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
人人都是产品经理
人人都是产品经理
P
Palo Alto Networks Blog
M
MIT News - Artificial intelligence
G
GRAHAM CLULEY
C
Check Point Blog
Apple Machine Learning Research
Apple Machine Learning Research
Last Week in AI
Last Week in AI
T
Troy Hunt's Blog
L
Lohrmann on Cybersecurity
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
量子位
博客园 - 聂微东
S
Securelist
博客园 - 三生石上(FineUI控件)
F
Full Disclosure
G
Google Developers Blog
L
LINUX DO - 热门话题
P
Proofpoint News Feed
AI
AI
PCI Perspectives
PCI Perspectives

CloudCannon Blog

Building with AI: Git-based vs headless vs traditional CMS CloudCannon + Astro: performance meets powerful content management Introducing the Astro Component Starter Introducing Jetstream — built on the Astro Component Starter Why we switched to the system font stack Redesigning CloudCannon’s docs with Diátaxis, Lume, and Pagefind Make content editing more visual: upgraded Editable Regions How Configuration Mode makes building editing interfaces easy Your hosting just got an upgrade (and a price cut) Custom testing domains for professional branding Keep your content consistent with input validation Managing multilingual content in CloudCannon Simplify team publishing with conflict resolution and domain tools Open Beta: Publishing Conflict Resolution Getting started with CloudCannon and Astro: Bookshop, components, and live editing Welcome to the CloudCannon Community! Omnichannel delivery is just marketing spin from API-based CMS companies Getting started with CloudCannon and Astro: Snippets and Collections Managing digital assets in CloudCannon: a guide to smart asset storage Understanding CloudCannon's branching workflows and Projects: a complete guide What is a static website? CloudCannon’s 2024 wrapped Getting started with CloudCannon and Astro: WYSIWYG blogging Jamstack vs. WordPress: reasons to make the change The top five static site generators for 2025 (and when to use them!) Free Jekyll themes for 2025: ten great community options Eleventy (11ty) vs. Hugo How to set up WYSIWYG editing with MkDocs Material The rise of static-first websites: why major brands are making the switch Watching your Core Web Vitals on Jamstack Understanding the difference between static, dynamic, and hybrid websites Looking for an alternative to Netlify CMS or Decap CMS? Designing components for your website editors: a CloudCannon case study Does my website look big in this? Six tips to lower your page weight Content is sacred — so own your revision history The eternal balancing act: load time vs. delay time Streamlined Headless Mode, Unified Configuration, and live data editing What is a headless CMS? Looking for a TinaCMS or Tina Cloud alternative? The ultimate guide to Hugo Sections Coming soon: Live config editing and data reloading Faster publishing workflows out now! Why information architecture matters for your website Website UX vs SEO: picking your battles Easily manage your multilingual Astro site in CloudCannon How you can optimize publishing workflows for your content team How you can optimize your CMS for SEO success How you can optimize your Content Editor for long-form articles How you can optimize your Visual Editor for page building Secure, swift, and stable: static sites for the financial sector Enhanced flexibility for teams with Custom Permissions Building static sites that scale The Inaugural 11ty International Symposium on Making Web Sites Real Good How to manage hundreds of connected websites with a Git-based headless CMS How we’re building CloudCannon for accessibility CloudCannon’s new editing improvements are here! Open Beta | New ways to collaborate on editing your websites Top 11 free Eleventy themes for 2024 Top 10 free Astro themes to use in 2024 Why choose a Git-based headless CMS over a monolithic DXP in 2024? Learning web development: a self-guided roadmap Partner Site of the Month: Blüthner Piano Centre, by Winteractive CloudCannon’s 2023 wrapup Let’s create a microblog with visual editing using Bookshop and Eleventy Update and visualize your branches with CloudCannon Projects What is a Git-based CMS and why you should use one CloudCannon secures SOC 2 certification The complete guide to growing your web development agency Automatically optimize your images with Eleventy Image and CloudCannon Share components and syndicate content with Site Mounting Partner Site of the Month: Cru Uncorked, by Ed Meehan New web component for responsive HTML tables Wrapping up HugoConf 2023 Partner Site of the Month: Van Dillen Antieke Bouwmaterialen, by Fulldev How to become a freelance web developer: a comprehensive guide Q3 2023: CloudCannon features and improvements 22 ways to deliver more value to your web development clients Partner Site of the Month: DC Gay Flag Football League, by Ed Cupaioli A new way to configure your CloudCannon sites CloudCannon — the official CMS partner of Eleventy Full CloudCannon support for Nuxt static sites Partner Site of the Month: Stadium Bike, by Insight Creative, Inc. HugoConf 2023, brought to you by CloudCannon DAM Support for Cloudflare R2 and DigitalOcean Spaces Eleventy (11ty) vs. Gatsby in 2023 – which SSG is best for you? How CloudCannon’s live editing works with Astro and Bookshop Partner Site of the Month: Fiducian, by Croissant & Baguette Eleventy (11ty) vs. Astro How to customize CloudCannon’s Client Sharing interface Let anyone, anywhere, edit your CloudCannon sites Top 23 free Astro themes for building out-of-this-world static sites in 2023 How Jampack optimizes our Eleventy website and improves performance Astro vs. Next.js CloudCannon.com is now built with Eleventy! Out-of-this-world support for all Astro users Introducing the CloudCannon Partner Program Full CloudCannon support for Gatsby Top 10 Free SvelteKit Themes for Building Lighting-Fast Static Sites in 2023 Enhanced CloudCannon support for Next.js users Upcoming CloudCannon Interface improvements (Open Beta)
Drupal vs Jekyll + CloudCannon
2015-09-24 · via CloudCannon Blog

There's a huge ecosystem of plugins and add-ons available for any CMS. In this comparison we'll be using the content management systems straight out of the box to reduce the complexity and time to get the sites live.

We're looking at Drupal, a powerful open source PHP CMS which has been around since 2000.

It’s the first time I’ve used Drupal so there might be better ways of doing things. If you can see an improvement, leave a comment below.


Site Overview Direct link to this section

The template we're using is called Blog which is made by Google as part of their Material Design Lite Framework.

I've made a few modifications to the theme to get it ready for our testing:

  • The front page is simplified so it only shows blog posts
  • There's a navigation at the top right
  • I added about.html which is a basic page with content
  • Instead of using classes to show the header image for the blog entries, I used inline styles so the CMS can just insert an image path
  • I removed the comments section and the next/previous links on a blog entry to keep the implementation as simple as possible

You can see the static site I started each integration with in this Git repository.

The home page lists all the blog posts.

There's an about page.

And a page to view a blog post.

In this scenario I'm a web designer making a website for a non-technical client. The client needs to update the about page and manage their blog without touching any code.


Setup Direct link to this section

Drupal Direct link to this section

I'm on Mac OS X so I decided to use MAMP to set up my PHP environment. After a 240MB download I had a full PHP and MySQL environment. Next, I downloaded Drupal 7, unzipped it to the htdocs directory inside MAMP and loaded the quick installer in my browser.

The quick install involved configuring the database and other site settings for my site.

Jekyll Direct link to this section

Again, I'm using Mac OS X so Ruby is already installed. To install Jekyll I open up my terminal and type:

sudo gem install jekyll

Then I can run Jekyll using:

jekyll serve

Development Direct link to this section

Drupal Direct link to this section

With Drupal, I made a copy of the Stark theme and read documentation on building Drupal themes. These are the files I added to the theme:

html.tpl.php: The outer most structure of the page and asset loading.

node.tpl.php: HTML structure for listing blog posts on the front page, normal pages and blog posts.


<?php if ($teaser) { ?>
<div class="mdl-card mdl-cell mdl-cell--12-col">
<div class="mdl-card__media mdl-color-text--grey-50" style="background-image: url('<?php echo file_create_url($content['field_image'][0]['#item']['uri']); ?>')">

<h3><a href="<?php print $node_url; ?>"><?php print $title; ?></a></h3>
</div>
<div class="mdl-card__supporting-text meta mdl-color-text--grey-600">
<div class="minilogo"></div>
<div>
<strong><?php echo $name ?></strong>
<span><?php print format_interval((time() - $node->created) , 2) . t(' ago'); ?></span>
</div>
</div>
</div>
<?php } elseif ($page) { ?>
<div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">
<div class="mdl-card__media mdl-color-text--grey-50">
<h3>About Me</h3>
</div>
<div class="mdl-color-text--grey-700 formatted-text mdl-card__supporting-text no-flex">
<?php print render($content); ?>
</div>
</div>
<?php } else { ?>
<div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">
<div class="mdl-card__media mdl-color-text--grey-50" style="background-image: url('<?php echo file_create_url($content['field_image'][0]['#item']['uri']); ?>')">
<h3><?php print $title; ?></h3>
</div>
<div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">
<div class="minilogo"></div>
<div>
<strong><?php echo $name ?></strong>
<span><?php print format_interval((time() - $node->created) , 2) . t(' ago'); ?></span>
</div>
<div class="section-spacer"></div>
<div class="meta__favorites">
425 <i class="material-icons" role="presentation">favorite</i>
<span class="visuallyhidden">favorites</span>
</div>
<div>
<i class="material-icons" role="presentation">bookmark</i>
<span class="visuallyhidden">bookmark</span>
</div>
<div>
<i class="material-icons" role="presentation">share</i>
<span class="visuallyhidden">share</span>
</div>
</div>
<div class="mdl-color-text--grey-700 formatted-text mdl-card__supporting-text">
<?php
hide($content['field_image']);
hide($content['comments']);
hide($content['links']);
print render($content);
?>

</div>
</div>
<?php } ?>

page--front.tpl.php: Container for front page HTML. Sits between html.tpl.php and the front page code in node.tpl.php.

page.tpl.php: Container for page HTML. Sits between html.tpl.php and the page/blog entry code in node.tpl.php.

region.tpl.php: Was outputting unwanted HTML so I set it to output nothing.


<?php print $content ?>

block.tpl.php: Was outputting unwanted HTML so I set it to output nothing.

template.php: Disabled Drupal's default CSS and JavaScript files. Also customised the menu item HTML output and added external CSS and JavaScript files.

All the posts and site settings are stored in the MySQL database.

It took me a long time and a lot of reading to figure out which files to edit or where generated HTML I didn't want was coming from.

The other gotcha is each time I made an update to the template I would have to go into the Drupal admin panel to clear the cache before I could see the changes:

Jekyll Direct link to this section

Using Jekyll, most of the static HTML files remained exactly the same. I pulled out the layouts into separate files to use on multiple pages:

default.html: Contains the basic HTML structure. All other layouts use this as their parent layout.

post.html: Defines the structure of blog posts.

page.html: Defines the structure of normal pages.

Blog posts are Markdown files. The title, author, header image and other metadata is set using front matter at the top of the file:


---
layout: post
title: Shopping
author: The Newist
header_image_path: '/assets/shopping.jpg'
---

Excepteur reprehenderit sint exercitation ipsum consequat qui sit id velit elit. Velit anim eiusmod labore sit amet. Voluptate voluptate irure occaecat deserunt incididunt esse in. Sunt velit aliquip sunt elit ex nulla reprehenderit qui ut eiusmod ipsum do. Duis veniam reprehenderit laborum occaecat id proident nulla veniam. Duis enim deserunt voluptate aute veniam sint pariatur exercitation. Irure mollit est sit labore est deserunt pariatur duis aute laboris cupidatat. Consectetur consequat esse est sit veniam adipisicing ipsum enim irure.

Qui ullamco consectetur aute fugiat officia ullamco proident Lorem ad irure. Sint eu ut consectetur ut esse veniam laboris adipisicing aliquip minim anim labore commodo. Incididunt eu enim enim ipsum Lorem commodo tempor duis eu ullamco tempor elit occaecat sit. Culpa eu sit voluptate ullamco ad irure. Anim commodo aliquip cillum ea nostrud commodo id culpa eu irure ut proident. Incididunt cillum excepteur incididunt mollit exercitation fugiat in. Magna irure laborum amet non ullamco aliqua eu. Aliquip adipisicing dolore irure culpa aute enim. Ullamco quis eiusmod ipsum laboris quis qui.

Cillum ullamco eu cupidatat excepteur Lorem minim sint quis officia irure irure sint fugiat nostrud. Pariatur Lorem irure excepteur Lorem non irure ea fugiat adipisicing esse nisi ullamco proident sint. Consectetur qui quis cillum occaecat ullamco veniam et Lorem cupidatat pariatur. Labore officia ex aliqua et occaecat velit dolor deserunt minim velit mollit irure. Cillum cupidatat enim officia non velit officia labore. Ut esse nisi voluptate et deserunt enim laborum qui magna sint sunt cillum. Id exercitation labore sint ea labore adipisicing deserunt enim commodo consectetur reprehenderit enim. Est anim nostrud quis non fugiat duis cillum. Aliquip enim officia ad commodo id.

To list the blog posts in index.html, I create a for loop and reference the front matter:


---
layout: default
title: Home
---

{% for post in site.posts %}
<div class="mdl-card mdl-cell mdl-cell--12-col">
<div class="mdl-card__media mdl-color-text--grey-50" style="background-image: url('{{ post.header_image_path }}')">
<h3><a href="{{ post.url }}">{{ post.title }}</a></h3>
</div>
<div class="mdl-card__supporting-text meta mdl-color-text--grey-600">
<div class="minilogo"></div>
<div>
<strong>{{ post.author }}</strong>
<span>{{ post.date | date: "%-d %B %Y" }}</span>
</div>
</div>
</div>
{% endfor %}

Jekyll site source


Deployment Direct link to this section

Drupal Direct link to this section

For Drupal I tried two ways of deploying to a production server.

First I set up an small EC2 server with Ubuntu 14.04 in US-West-1. Then I SSHed into the server to install the PHP/MySQL environment using this guide. I downloaded Drupal, ran the installer to set up my site and configure the database. Then finally transferred my theme across and imported my development database using PHPMyAdmin.

The second way I tried was using a paid service called SiteGround. I could have used cPanel to do a one click install of Drupal but I wanted to keep the environment as close as I could to developement. I uploaded Drupal and my theme using FTP, ran the quick install, then imported my development database using PHPMyAdmin.

Overall using SiteGround saved me a lot of time as I didn't have to set up an entire PHP environment.

Jekyll Direct link to this section

I used CloudCannon to deploy and host the Jekyll site. To do this I created a GitHub repository with my source files, then connected that repository to a new site in CloudCannon.

The files sync to CloudCannon and are live on a generated testing domain.

All the content is in the files so there is no database.


Updating Content Direct link to this section

Drupal Direct link to this section

To update content in Drupal you use the admin panel. You can see existing articles and pages.

Update content using a text area.

And you can update other metadata.

Jekyll Direct link to this section

In CloudCannon, editing is inline. You can update content on the about page by clicking and entering new content.

Going to the collections view displays all the blog posts.

You write and update blog posts in a simple editor.

Update front matter in the settings sidebar.

All changes made on CloudCannon are committed back to the repository so I can work on the site locally in tandem.


Speed Direct link to this section

Drupal Direct link to this section

I had the following cache settings turned on and loaded the page several times to ensure everything was cached properly.

For a further speed increase, one of our readers suggested using the Boost module.

Jekyll Direct link to this section

CloudCannon serves static files and all assets are minified, optimised and delivered on a CDN.

Comparison Direct link to this section

I used a free tool from MaxCDN to compare the load times from different parts of the world.


Conclusion Direct link to this section

I felt like I was fighting against Drupal every step of the way. It was hard to take a static page and convert it into a Drupal theme, deployment took several steps, the client editing was powerful but displayed many complicated options and the end website was more than six times slower.

Jekyll was a small step from the static website, deployment was a simple git push, the editing was all inline and the website was significantly faster.

All the source files are available on GitHub: