From 114ad5aa218c4366330c4135acbf7dbc4a4b89be Mon Sep 17 00:00:00 2001 From: Anthony Dillon Date: Mon, 29 Nov 2021 12:14:14 +0000 Subject: [PATCH] Add the local blog system to the site (#643) * Add the local blog system to the site * Fix the descritpion part * Fix lint issue * Align the logo and article to the left content edge --- requirements.txt | 1 + static/sass/_patterns_cards.scss | 132 +++++++++++++++++ static/sass/main.scss | 16 ++- templates/base_index.html | 7 + templates/blog/article.html | 91 ++++++++++++ templates/blog/index.html | 135 ++++++++++++++++++ templates/blog/partials/_blog-card.html | 23 +++ templates/blog/partials/_blog-card_aside.html | 9 ++ .../blog/partials/_blog-card_featured.html | 20 +++ templates/includes/head.html | 2 +- templates/includes/header.html | 3 + templates/index.html | 8 +- webapp/app.py | 2 + webapp/blog/__init__.py | 0 webapp/blog/views.py | 87 +++++++++++ 15 files changed, 527 insertions(+), 9 deletions(-) create mode 100644 static/sass/_patterns_cards.scss create mode 100644 templates/blog/article.html create mode 100644 templates/blog/index.html create mode 100644 templates/blog/partials/_blog-card.html create mode 100644 templates/blog/partials/_blog-card_aside.html create mode 100644 templates/blog/partials/_blog-card_featured.html create mode 100644 webapp/blog/__init__.py create mode 100644 webapp/blog/views.py diff --git a/requirements.txt b/requirements.txt index f707697d..25a2cfa2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ canonicalwebteam.flask_base==0.9.1 +canonicalwebteam.blog==6.4.0 canonicalwebteam.discourse-docs==1.0.1 canonicalwebteam.http==1.0.3 canonicalwebteam.templatefinder==1.0.0 diff --git a/static/sass/_patterns_cards.scss b/static/sass/_patterns_cards.scss new file mode 100644 index 00000000..e05c8ba0 --- /dev/null +++ b/static/sass/_patterns_cards.scss @@ -0,0 +1,132 @@ +@mixin maas-p-cards { + @include local-blog-card; +} + +@mixin local-blog-card { + .p-blog-card { + @extend %p-card--highlighted; + + border-top: 3px solid $color-brand; + } + + .blog-p-card__category { + color: $color-mid-dark; + font-size: $sp-medium; + line-height: 1.5; + padding: 0 0 0 $sp-large; + text-transform: uppercase; + + > a:link, + > a:visited { + color: $color-mid-dark; + text-decoration: none; + } + + > a:hover, + > a:active { + color: $color-brand; + text-decoration: underline; + } + } + + %post-card-header { + border-radius: 2px; + padding: $sp-medium $sp-medium $sp-small; + } + + .blog-p-card--post { + @extend %p-card--highlighted; + + display: flex !important; + flex-direction: column; + padding: 0; + + .p-strip--featured & { + background-color: rgba(255, 255, 255, 0.9); + position: relative; + z-index: 1; + } + + > .blog-p-card__content { + border-top: 1px solid $color-mid-light; + display: flex; + flex-direction: column; + height: 100%; + margin: 0; + padding: $sp-medium $sp-small $sp-small; + + > a, + h3, + p { + display: block; + margin: $sp-small 0; + } + } + + .blog-p-card__footer { + border-top: 1px dotted $color-mid-light; + font-size: 0.875rem; + margin: auto $sp-small 0; + max-width: inherit; + padding: $sp-medium $sp-small; + } + } + + .blog-p-card__header { + &--canonical-announcements { + border-color: #ff8936; + } + + &--cloud-and-server { + border-color: #a87ca0; + } + + &--desktop { + border-color: #faba54; + } + + &--internet-of-things { + border-color: #8db255; + } + + &--phone-and-tablet { + border-color: $color-mid-light; + } + + &--webinar { + border-color: #48929b; + } + + &--tutorials { + border-color: #47919e; + } + } + + .blog-p-card--muted { + @extend .p-card; + + background-color: $color-light; + box-shadow: 0 1px 2px 0 transparentize($color-dark, 0.8); + padding: 0; + + > .blog-p-card__header { + border-bottom: 0; + border-top: 3px solid $color-light; + margin-bottom: 0; + } + + > .blog-p-card__content { + border-top: 1px dotted $color-mid-light; + margin: 0 $sp-small $sp-small; + padding: $sp-medium $sp-small $sp-small; + } + } + + .blog-p-card__date { + @extend .p-media-object__meta-list; + + display: flex; + margin-top: auto; + padding-top: $sp-medium; + } +} diff --git a/static/sass/main.scss b/static/sass/main.scss index 2a859833..714564d6 100644 --- a/static/sass/main.scss +++ b/static/sass/main.scss @@ -2,6 +2,7 @@ @import "settings_colors"; $increase-font-size-on-larger-screens: false; +$breakpoint-navigation-threshold: 960px; // import vanilla-brochure-theme @import "vanilla-framework/scss/build"; @@ -13,7 +14,7 @@ $increase-font-size-on-larger-screens: false; @import "patterns_strips", "patterns_hero-video", "patterns_lists", "patterns_modal", "patterns_takeunders", "patterns_tables", "patterns_contact-modal", "layout_docs", "patterns_sidenav", "hljs", - "patterns_tutorials"; + "patterns_tutorials", "patterns_cards"; // patterns @include maas-p-hero-video; @@ -26,6 +27,7 @@ $increase-font-size-on-larger-screens: false; @include maas-l-docs; @include maas-p-sidenav; @include maas-p-tutorials; +@include maas-p-cards; .row.is-bordered::before { left: 0; @@ -68,9 +70,15 @@ $increase-font-size-on-larger-screens: false; } } -.p-navigation__banner { - background-color: #e95420; - padding-left: 1rem; +.p-navigation__row { + @media screen and (min-width: $breakpoint-navigation-threshold) { + padding: 0 1.5rem; + } + + .p-navigation__banner { + background-color: #e95420; + padding-left: 1rem; + } } // XXX Ant: This fixes an issue with the use of dark navigation. diff --git a/templates/base_index.html b/templates/base_index.html index a7e5b5e5..c2eef15c 100644 --- a/templates/base_index.html +++ b/templates/base_index.html @@ -9,6 +9,13 @@ {% include "includes/head.html" %} {% endwith %} {% if self.meta_copydoc() %}{% endif %} + {% block extra_meta %}{% endblock %} + + {% if self.meta_image %} + + + + {% endif %} diff --git a/templates/blog/article.html b/templates/blog/article.html new file mode 100644 index 00000000..eaf3ac5c --- /dev/null +++ b/templates/blog/article.html @@ -0,0 +1,91 @@ +{% extends "base_index.html" %} + +{% block page_title %}{{ article.title.rendered|safe }} | Snapcraft{% endblock %} +{% block page_description %}{{ article.excerpt.raw }}{% endblock %} +{% if article.image and article.image.source_url %} + {% block meta_image %}{{ article.image.source_url }}{% endblock %} +{% endif %} + +{% block meta_schema %} + +{% endblock %} + +{% block extra_meta %} + + + +{% endblock %} + +{% block content %} +
+ {% if newsletter_subscribed %} +
+
+

+

Success
+

Thanks for subscribing!

+
+
+ + {% endif %} +
+
+

{{ article.title.rendered|safe }}

+

by {{ article.author.name }} on {{ article.date }}

+ {{ article.content.rendered|safe }} +
+
+
+ +{% if related_articles %} +
+
+

+ Related posts +

+
+
+ {% for related_article in related_articles %} +
+

+ + {{ related_article.title.rendered|safe }} + +

+

{{ related_article.excerpt.raw }}

+
+ {% endfor %} +
+
+{% endif %} + + +{% endblock %} diff --git a/templates/blog/index.html b/templates/blog/index.html new file mode 100644 index 00000000..d5535a10 --- /dev/null +++ b/templates/blog/index.html @@ -0,0 +1,135 @@ +{% extends "base_index.html" %} + + +{% block page_title %}blog - Updates, ideas, and inspiration from MAAS.{% endblock %} +{% block extra_meta %} + +{% endblock %} + +{% block content %} + +
+ {% if current_page == 1 %} +
+ {% set all_articles = featured_articles + articles %} + {% for article in all_articles %} + {% if loop.index <= 1 %} + {% include 'blog/partials/_blog-card_featured.html' %} + {% endif %} + {% endfor %} +
+
    + {% for article in all_articles %} + {% if loop.index > 1 and loop.index <= 4 %} + {% include 'blog/partials/_blog-card_aside.html' %} + {% endif %} + {% endfor %} +
+

+ + Join the community + +

+
+
+ +
+ {% for article in articles %} + {% if loop.index >= 4 %} + {% include 'blog/partials/_blog-card.html' %} + {% endif %} + {% endfor %} +
+ {% else %} +
+ {% set all_articles = featured_articles + articles %} + {% for article in all_articles %} + {% include 'blog/partials/_blog-card.html' %} + {% endfor %} +
+ {% endif %} + +
+
    + + {% if current_page > 1 %} +
  1. + + Previous page + +
  2. + {% else %} +
  3. + Previous page +
  4. + {% endif %} + + {# always show 5 pages in pagination #} + {% if current_page > 4 and current_page == total_pages %} +
  5. + {{ current_page - 4 }} +
  6. + {% endif %} + + {% if current_page > 3 and current_page >= total_pages - 1 %} +
  7. + {{ current_page - 3 }} +
  8. + {% endif %} + + {% if current_page > 2 %} +
  9. + {{ current_page - 2 }} +
  10. + {% endif %} + + {% if current_page > 1 %} +
  11. + {{ current_page - 1 }} +
  12. + {% endif %} + + +
  13. + {{ current_page }} +
  14. + + {% if current_page < total_pages %} +
  15. + {{ current_page + 1 }} +
  16. + {% endif %} + + {% if current_page < total_pages - 1 %} +
  17. + {{ current_page + 2 }} +
  18. + {% endif %} + + {% if current_page < total_pages - 2 and current_page <= 2 %} +
  19. + {{ current_page + 3 }} +
  20. + {% endif %} + + {% if current_page < total_pages - 3 and current_page == 1 %} +
  21. + {{ current_page + 4 }} +
  22. + {% endif %} + + {% if current_page != total_pages %} +
  23. + + Next page + +
  24. + {% else %} +
  25. + Next page +
  26. + {% endif %} +
+
+
+{% endblock %} diff --git a/templates/blog/partials/_blog-card.html b/templates/blog/partials/_blog-card.html new file mode 100644 index 00000000..aec86a00 --- /dev/null +++ b/templates/blog/partials/_blog-card.html @@ -0,0 +1,23 @@ +
+ {% if article.group %} +
+
{{ article.group.name }}
+
+
+ {% endif %} +
+ {% if article.image and article.image.source_url %} + + {% endif %} +

+ {{ article.title.rendered|safe }} +

+

by {{ article.author.name }} on {{ article.date }}

+ {% if not article.image %} +

{{ article.excerpt.raw }}

+ {% endif %} +
diff --git a/templates/blog/partials/_blog-card_aside.html b/templates/blog/partials/_blog-card_aside.html new file mode 100644 index 00000000..a1b938f7 --- /dev/null +++ b/templates/blog/partials/_blog-card_aside.html @@ -0,0 +1,9 @@ +
  • +

    {{ article.group.name }}

    +
    + + {{ article.title.rendered|safe }} + +
    +

    by {{ article.author.name }} on {{ article.date }}

    +
  • diff --git a/templates/blog/partials/_blog-card_featured.html b/templates/blog/partials/_blog-card_featured.html new file mode 100644 index 00000000..18879ded --- /dev/null +++ b/templates/blog/partials/_blog-card_featured.html @@ -0,0 +1,20 @@ +
    + {% if article.group %} +
    +
    {{ article.group.name }}
    +
    +
    + {% endif %} + {% if article.image and article.image.source_url %} + + {% endif %} +

    + {{ article.title.rendered|safe }} +

    +

    by {{ article.author.name }} on {{ article.date }}

    + {% if not article.image %} +

    {{ article.excerpt.raw }}

    + {% endif %} +
    diff --git a/templates/includes/head.html b/templates/includes/head.html index fda4470f..26ef3ec1 100644 --- a/templates/includes/head.html +++ b/templates/includes/head.html @@ -14,7 +14,7 @@ - + diff --git a/templates/includes/header.html b/templates/includes/header.html index e437a422..fc0035f4 100644 --- a/templates/includes/header.html +++ b/templates/includes/header.html @@ -25,6 +25,9 @@
  • Docs
  • +
  • + Blog +
  • Tutorials
  • diff --git a/templates/index.html b/templates/index.html index bb7e1305..31ed3ebe 100644 --- a/templates/index.html +++ b/templates/index.html @@ -743,8 +743,8 @@

    Enterprise support
    for MAAS

    -

    + The latest MAAS news

    Loading...
    @@ -767,8 +767,8 @@

    { articlesContainerSelector: "#latest-articles", articleTemplateSelector: "#articles-template", - hostname: "ubuntu.com", - gtmEventLabel: "ubuntu.com homepage", + hostname: "maas.io", + gtmEventLabel: "maas.io homepage", tagId: 1304 // MAAS tag ID } ) diff --git a/webapp/app.py b/webapp/app.py index fff03bfa..520f682f 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -18,6 +18,7 @@ from canonicalwebteam.templatefinder import TemplateFinder from canonicalwebteam.search import build_search_view from canonicalwebteam import image_template +from webapp.blog.views import init_blog from webapp.feeds import get_rss_feed from webapp.doc_parser import FastDocParser @@ -165,3 +166,4 @@ def index(): tutorials_docs.init_app(app) +init_blog(app, "/blog") diff --git a/webapp/blog/__init__.py b/webapp/blog/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/webapp/blog/views.py b/webapp/blog/views.py new file mode 100644 index 00000000..571a8c56 --- /dev/null +++ b/webapp/blog/views.py @@ -0,0 +1,87 @@ +import flask +import talisker + +from canonicalwebteam.blog import ( + BlogViews, + BlogAPI, + build_blueprint, +) +from dateutil import parser + + +def init_blog(app, url_prefix): + session = talisker.requests.get_session() + blog_api = BlogAPI( + session=session, + thumbnail_width=354, + thumbnail_height=199, + ) + blog = build_blueprint( + BlogViews( + api=blog_api, + blog_title="MAAS Blog", + tag_ids=[1304], + excluded_tags=[3184, 3265, 3408], + ) + ) + + @blog.context_processor + def add_newsletter(): + newsletter_subscribed = flask.request.args.get( + "newsletter", default=False, type=bool + ) + + return {"newsletter_subscribed": newsletter_subscribed} + + @blog.route("/sitemap.xml") + def sitemap(): + base_url = "https://maas.io/blog" + links = [] + page = 1 + while True: + url = ( + f"https://ubuntu.com/blog/wp-json/wp/v2/posts?" + f"tags=1304&per_page=100&page={page}" + f"&tags_exclude=3184%2C3265%2C3408" + ) + + response = session.get(url) + if response.status_code == 400: + break + + try: + blog_response = response.json() + except Exception: + continue + + for post in blog_response: + try: + date = ( + parser.parse(post["date"]) + .replace(tzinfo=None) + .strftime("%Y-%m-%d") + ) + links.append( + { + "url": base_url + "/" + post["slug"], + "last_udpated": date, + } + ) + except Exception: + continue + + page = page + 1 + + xml_sitemap = flask.render_template( + "sitemap/sitemap.xml", + base_url=base_url, + links=links, + ) + + response = flask.make_response(xml_sitemap) + response.headers["Content-Type"] = "application/xml" + response.headers["Cache-Control"] = "public, max-age=43200" + + return response + + app.register_blueprint(blog, url_prefix=url_prefix)