Building a Markdown-based CMS Inside your Flask Web App Course

Course Summary

Are you deciding whether to build a Python web app in Flask or go with a CMS like Wordpress? This can seem like an either/or decision. Either, you can have a great data-driven web app or some clunky PHP thing that marketing and other folks can use to create the site.

But as you'll learn in this course, it's quite easy to add a powerful CMS to your existing web app!

What students are saying

Modern Python Projects has and continues to provide valuable insight, that has aided my development workflow and given me knowledge of tools that I otherwise wouldn't. I heartily recommend this course to all practitioners of Python.
-- Umar

Source code and course GitHub repository

github.com/talkpython/adding-a-cms-to-your-web-app-course

What's this course about and how is it different?

This unique course shows you how to leverage your existing skills in your Python web framework and the huge investment you have made in building a scalable application on the web to add a user-friendly, high-performance CMS capability right on top of that app. You can add these features without modifying your existing site's behavior or (besides startup) the existing code.

If you have wished you could simply sign in to your site and add new functionality, pages, redirects, and more but have scoffed at adding a separate CMS like app layer on the side, this is for you.

We treat you as knowledgeable Flask developers who need to add this cool functionality to empower your team to do more on their own with your site.

We will start from first principles of routing, views, and templates to help you have full control over this CMS functionality, just like you have for the rest of your web app.

Flask or Pyramid web framework?

This course comes in two flavors. Pick the one that makes you happy:

Get the CMS + Web Foundations Bundle

Both courses with CMS Web Bundle

We created a special bundle of courses including the foundation web course as well as this CMS course in two web frameworks, Flask and Pyramid. Check it out and get two for the price of one.

What topics are covered

In this course, you will:

  • Learn how to have data-driven pages and CMS pages coexist in your app
  • Add CMS pages to your existing website or a new website you're just launching
  • AVOID running a parallel WordPress or Joomla site for this CMS-like functionality
  • Take full advantage of the capabilities of your site while working with landing pages and other CMS elements
  • Allow marketing teams, business teams, and others to edit site safely and professionally
  • Employ the markdown-subtemplate package for extreme performance
  • Use markdown-subtemplate's content reuse features for creating shared elements across pages
  • Write markdown content and render rich HTML
  • Use a proper, full-featured markdown editor on your admin backend for a professional and polished experience for your internal users
  • Add the CMS superpower to your web app
  • And lots more

View the full course outline.

Who is this course for?

This course is for anyone who has or is creating a Flask web application and would like a much better way to fully round out the content of the site.

Yes, every web app will need some data-driven elements. If you ran a book store, there would be a page showing the book details: cover, title, price, summary, etc. But you would also have a contact us page, a privacy policy page, a landing page for a marketing campaign, and on and on. If you want to create all that other content without writing new code and redeploying the site, then this course is for you.

As far as knowledge prerequisites, we assume that anyone taking this course has basic knowledge of:

  • Python (you can write a function, create a class, reuse elements via import)
  • Flask
  • HTML and CSS

What will we build?

In this course, we take an existing web application and add this CMS capability to it. We will start with a clone of the PyPI website (pypi.org) written in Flask.

Then we will systematically add our CMS features to that application. We will add the ability to have arbitrary redirects in the URL structure (think bit.ly) *as well as *full pages (think WordPress). Once we can capture and render these, we will add a deep admin section with a proper markdown editor and other capabilities to the app.

Concepts backed by concise visuals

While exploring a topic interactively with demos and live code is very engaging, it can mean losing the forest for the trees. That's why when we hit a new topic, we stop and discuss it with concise and clear visuals.

Here's an example of how routing works and a given URL is mapped to an appropriate view method.

Example: Concepts backed by concise visuals

Get hands-on for almost every chapter

Learning to code is an interactive experience. That's why it's important to write code and explore the apps we are building during this course.

Each chapter has code for the app as it began and as it finished. You are encouraged to follow along and create the relevant part of the CMS features after each chapter. You can start with the same code we do in the course and if you ever get lost, "reset" your progress by jumping in at that chapter.

Here's the GitHub repo structure that you can explore now to see what we're talking about.

Example: Code snapshotted at each chapter

This course is delivered in very high resolution

Example of 1440p high res video

This course is delivered in 1440p (4x the pixels as 720p). When you're watching the videos for this course, it will feel like you're sitting next to the instructor looking at their screen.

Every little detail, menu item, and icon is clear and crisp. Watch the introductory video at the top of this page to see an example.

Follow along with subtitles and transcripts

Each course comes with subtitles and full transcripts. The transcripts are available as a separate searchable page for each lecture. They also are available in course-wide search results to help you find just the right lecture.

Each course has subtitles available in the video player.

Who am I? Why should you take my course?

Who is Michael Kennedy?

My name is Michael, nice to meet you. ;) There are a couple of reasons I'm especially qualified to teach you Python.

 1. I'm the host of the #1 podcast on Python called Talk Python To Me. Over there, I've interviewed many of the leaders and creators in the Python community. I bring that perspective to all the courses I create.

 2. I've been a professional software trainer for over 10 years. I have taught literally thousands of professional developers in hundreds of courses throughout the world.

 3. Students have loved my courses. Here are just a few quotes from past students of mine.

"Michael is super knowledgeable, loves his craft, and he conveys it all well. I would highly recommend his training class anytime." - Robert F.
"Michael is simply an outstanding instructor." - Kevin R.
"Michael was an encyclopedia for the deep inner workings of Python. Very impressive." - Neal L.

Free office hours keep you from getting stuck

One of the challenges of self-paced online learning is getting stuck. It can be hard to get the help you need to get unstuck.

That's why at Talk Python Training, we offer live, online office hours. You drop in and join a group of fellow students to chat about your course progress and see solutions via screen sharing.

Just visit your account page to see the upcoming office hour schedule.

The time to act is now

On the internet, content is king. You interact with customers and rank in search engines based on the pages on your site. Take this course and you'll have the most tightly integrated experience for quickly adding content to your app. Your users will not be able to tell the difference between the CMS side and the structured side of your app.

Join this course today! You've got nothing to lose. Every one of our courses comes with a 2-week money-back guarantee.

BTW, this page, along with many others on our site, was created with exactly this technique which we have extracted into a framework for this course. ;)

Course Outline: Chapters and Lectures

Welcome to the course
12:07
Welcome to the course
4:28
What we'll cover
4:37
Student expectations
2:22
Meet your instructor
0:40
Course setup and requirements
5:27
Get the right Python version
2:05
Our code editor
2:16
git the source code
1:06
A tour of our demo application
13:16
A tour of our demo app
2:37
Exploring the starter source code
6:45
Getting the app up and running
3:54
Routing for the CMS
37:14
What is routing
4:24
Routing examples
4:47
Examining the existing routes
5:56
Adding THE cms route
5:58
The cms_service
7:35
Concept: Adding the cms route
1:39
A better 404 error page
1:33
Adding our 404 page
5:22
The redirects (our bit.ly)
1:19:11
Redirect introduction
1:42
Keeping the query string
7:43
Concept: ViewModels
2:02
Demo: creating the ViewModel
8:51
Adding the admin section
1:19
Demo: Admin section
10:35
Listing redirects
9:35
Concept: GET-POST-Redirect
2:29
Add redirect view methods
5:31
Add redirect HTML form
6:19
Capturing data from the form
10:19
Creating the redirect
3:36
Editing a redirect
7:20
Cleaning up the HTML
1:50
The pages (our WordPress)
34:38
CMS Page introduction
3:39
Adding the page template
7:46
Rendering real page content
3:25
Concept: Rendering pages
1:37
Admin page listings
3:52
Adding a CMS page with the admin
9:06
Editing CMS pages
5:13
Saving content to the DB
41:11
Saving pages to the database
1:06
Need to learn SQLAlchemy?
1:35
Tour of existing DB layer
6:23
Creating the Page class
5:42
Creating the Redirects class
2:28
Saving a Redirect
8:38
Using the new Redirect class
4:42
Saving a Page
4:26
Using pages from DB
3:49
Concept: Inserting data with SQLAlchemy
1:05
Concept: Query for an object with SQLAlchemy
1:17
Markdown as our format
18:50
Problem with HTML
3:18
Adding markdown content
4:17
Markdown to HTML
8:34
Extras in markdown
1:53
Concept: Rendering markdown
0:48
Rich editors
13:49
Choosing a markdown editor
1:55
Demo: Installing SimpleMDE
3:14
Concept: Installing SimpleMDE
1:43
Using SimpleMDE
5:44
Concept: Using SimpleMDE
1:13
Advanced markdown
53:04
Shortingcomings of pure markdown
4:22
Markdown-subtemplates
3:17
Using markdown-subtemplate in the viewmodel
2:45
Custom storage engine
7:48
Using shared content, first pass
3:47
Formatted elements and custom HTML
5:05
Marking pages as shared in the DB
6:25
Add is_shared to the editor
5:31
Saving shared state
1:31
Visualizing shared pages
3:21
Restricting shared content
5:03
Concept: Markdown subtemplate integration
2:05
Caching integration recommended
2:04
Logging activity
21:16
Logging motivation
1:46
Current logging with Logbook
1:04
Demo: Tour of logging
5:44
Adding admin logging
3:07
Setting markdown log levels
3:07
Integration with Logbook
4:37
Concept: Setting markdown log level
0:52
Concept: Logger integration
0:59
Course conclusion
23:06
You've done it
1:35
Review: CMS routing
4:21
Review: Redirects
1:14
Review: ViewModels
1:40
Review: Data-driven vs cms pages
2:32
Review: Rendering page
2:29
Review: Inserting with SQLAlchemy
0:56
Review: The problem with HTML
1:34
Improving markdown
3:39
Review: logging
1:54
Thanks and goodbye
1:12
Appendix: Modeling data with SQLAlchemy classes
54:50
Introducing SQLAlchemy
4:07
Who uses SQLAlchemy?
1:35
Architecture
2:14
The database model
3:10
Modeling packages
8:31
SQLAlchemy model base class
1:51
Connecting to our 'database'
6:01
Creating tables
6:26
Indexes
5:00
The rest of the tables
4:24
Relationships
7:16
Concepts: Modeling
4:15
Appendix: Using SQlAlchemy
52:56
Creating the basic insert script
2:18
Connecting to the database (again)
1:36
Setting package values
1:33
Setting package values
3:36
Running the inserts
2:34
Adding type hints to the session factory
1:20
Inserting real PyPI data
5:09
Concept: Unit of work
2:22
Querying data: Home page
5:55
Querying data: Latest releases
9:03
Working with package details
9:18
Concept: Querying data
4:03
Concept: Ordering data
0:44
Concept: Database updates
0:49
Concept: Relationships
1:59
Concept: Inserting data
0:37
Buy for $49 + tax Bundle and save 85% Team Gift

Questions? Send us an email: contact@talkpython.fm

Talk Python's Mastodon Michael Kennedy's Mastodon