Express Blog (#1519)

* Issue #1483
- add blog post to header
- add min height to posts page
- add blog/posts index page

* Issue #1483
- add single template style to posts page; will handle all post displays
- build posts template styles

* Issue #1483
- add futher posts index styles (based on shopify blog UI)
- remove parens in liquid

* Issue #1483
- liquid func to strip out top part of excerpt
- add active to first item

* Issue #1483
- add gutter links for tags
- add JS to handle gutter tags
- add CSS for gutter + posts
- add blog specfic layout

* Issue #1483
- add search bar style adjustments

* Issue #1483
- adjust tags side menu and remove from workflow
- add in second side menu
- add How To write Post page
- add more styles

* Issue #1483
- add example post page layout
- add all links to side menu

* Issue #1483
- readd post width 100%; imgs are not all same size this way
- add border to post
- change menu text color
- save 3 sample posts to use for preview - will need deletig

* Issue #1483
- update file names

* Issue #1483
- change file name

* Issue #1483
- change updated file name
- fix wrong example link
- fix wrong div placement

* PR #1519
- remove example post
- add Posts menu to gutter

* PR #1519
- add href to posts menu
- add styles to post menu
- adjust dark styles to post menu

* PR #1519
- adjust posts filter author
- add Welcome post

* PR #1519
- small text changes

* PR #1519
- revamp write a post instructions
- re-name css variables
- increase post font size
- add custom image to blog
- add comment about img

* PR #1519
- adjust headings
- small adjust content

* PR #1519
- add new line about pre-approval

* Update css/style.css

Co-authored-by: Michael Esteban <mickel13@gmail.com>

* PR #1519
- add bullet about how to use preview feature

* PR #1519
- fix typo

* fix typo

* Update 2024-05-25-welcome-post.md

Some edits to the initial blog post.

* Update 2024-05-25-welcome-post.md

- Add blank subtitle

* PR #1519
- remove image and related markup/css

* Add blog to jekyll config, update blog layout template

* PR #1519
- move more to config
- add conds to all to avoid errors in layout
- remove excerpt sep since it's not needed

* PR #1519
- remove quotes
- update write file

* PR #1519
- lower transition fade time

* Further changes, hopefully close to final

* Fix issues that Chris raised, etc.

* Add all posts to blog menu

* Change link for Blog menu item to latest post

* PR #1519
- add mobile styles to write.md image
- remove unused cond in post.html
- remove active class in post.md

* PR #1519 Small styles remove dummies
- remove dumm posts
- move inline styles from post
- remove css comments
- add small margins

* PR #1519
- Remove image
- undo css first child change

---------

Co-authored-by: Michael Esteban <mickel13@gmail.com>
Co-authored-by: Rand McKinney <crandmck@yahoo.com>
This commit is contained in:
Chris Del
2024-07-22 10:43:44 -06:00
committed by GitHub
parent 0eff3bf285
commit e4811a1f83
12 changed files with 421 additions and 34 deletions

View File

@@ -1,5 +1,15 @@
# Site settings
defaults:
-
scope:
path: "_posts"
type: "posts"
values:
layout: "post"
menu: blog
lang: en
# Build settings
markdown: kramdown

View File

@@ -0,0 +1,12 @@
<div id="blog-side-menu-container">
<h3>
<a href="/{{ page.lang }}/blog/posts">Posts</a>
</h3>
<ul id="blog-side-menu">
{% for post in site.posts %}
<li>
<a href="{{post.url}}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
</div>

View File

@@ -0,0 +1,10 @@
<ul id="tags-side-menu">
{% for tag in site.tags %}
<li>{{ tag[0] }}</li>
<ul
{% for post in tag[1] %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% endfor %}
</ul>

View File

@@ -141,6 +141,23 @@
</li>
</ul>
</li>
<li>
<ul id="blog-menu" class="menu">
<li><a href="{{site.posts.first.url}}"{% if page.menu == 'blog' %} class="active"{% endif %}>Blog</a>
<ul>
<li>
<a href="{{site.posts.first.url}}">Latest post</a>
</li>
<li>
<a href="/{{ page.lang }}/blog/posts.html">All posts</a>
</li>
<li>
<a href="/{{ page.lang }}/blog/write-post.html">Write a Post</a>
</li>
</ul>
</li>
</ul>
</li>
<!--
<li>
<ul id="changelog-menu" class="menu">

39
_layouts/post.html Normal file
View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<!---
Copyright (c) 2016 StrongLoop, IBM, and Express Contributors
License: MIT
-->
<html lang="{{ page.lang }}">
{% include head.html %}
<body>
<section class="content">
{% include header/header-{{ page.lang }}.html %}
{% include blog/posts-menu.md %}
<div id="overlay"></div>
<div id="blog-doc" markdown="1">
{% if page.title %}
<h1>{{page.title}}</h1>
{% endif %}
{% if page.sub_title %}
<h2>{{page.sub_title}}</h2>
{% endif %}
<div class="blog-details">
{% if page.author %}
<div class="blog-author">By {{page.author}}</div>
{% endif %}
<div class="blog-date">{{page.date| date: "%d %b %Y" }}</div>
</div>
{{ content }}
</div>
</section>
{% include footer/footer-{{ page.lang }}.html %}
</body>
</html>

View File

@@ -0,0 +1,18 @@
---
title: Welcome to The Express Blog!
tags: site-admin
author: Rand McKinney and Chris Del
---
Welcome to the new Express blog! The blog is meant to be a primary means of communication for the Express technical committee (TC). While we currently have other channels such as X, LinkedIn, and of course GitHub, there's no authoritative "soapbox" for announcements and general communication.
Initially, the Express blog will be a venue:
- For periodic announcements of new releases, pre-releases, plans, and ongoing work on the project.
- For the Express TC to discuss issues of particular importance to the Express community.
- To highlight security issues or other urgent information.
Eventually, we hope the blog will evolve into a more general communication hub for the entire Express community; for example to share examples, tips, and experiences with the Express ecosystem and other information that's not simply technical documentation or GitHub discussion.
Initially, posts will be written by TC members (potentially collaborating others), mainly because we don't have bandwidth to review general posts from the broader community. Eventually, we would love to open up the blog for broader contributions, but for now the focus is on trying to release Express 5.0, and the reality of an open-source project is that everyone has finite time to contribute.
If you think you have a great idea for a post for future consideration, feel free to pitch the idea! The best approach is to open a new issue, and then after appropriate discussion, open a PR. We've also written up simple [instructions to create a blog post](/en/blog/write-post.html).

View File

@@ -1,11 +1,14 @@
:root {
--main_dark_bg: #010409;
--second_dark_bg: #0d1117;
--darker_hover: #171b20;;
--dark_hover: #383838;
--second_dark_hover: #484848;
--dark_text: #e6edf3;
--dark_inner_text: #888888;
--dark_header_text: silver;
--dark_inner_text: grey;
--dark_main_text: #e6edf3;
--dark_bright_text: wheat;
--dark_border: #ddd;
--link: #259dff;
}
#theme-icon-container {
@@ -40,24 +43,24 @@ html.dark-mode #theme-icon-container .hidden-dark {
display: none;
}
html.dark-mode #theme-icon-container {
color: var(--dark_text);
color: var(--dark_main_text);
background-color: var(--second_dark_bg);
}
html.dark-mode > body {
background: var(--main_dark_bg);
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode header {
background-color: var(--second_dark_bg);
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode #logo > a {
color: var(--dark_text);
color: var(--dark_main_text);
}
/* navbar links/drop down menu links */
html.dark-mode #navbar ul#navmenu li a,
html.dark-mode #navbar ul#navmenu li.dropit-trigger a {
color: var(--dark_text);
color: var(--dark_main_text);
}
/* first drop down link - some js is adding current class */
html.dark-mode #navbar ul#navmenu li a.current {
@@ -82,12 +85,12 @@ html.dark-mode #navbar > span.algolia-autocomplete > input {
}
html.dark-mode #navbar > span.algolia-autocomplete > input,
html.dark-mode #navbar > span.algolia-autocomplete > input::placeholder {
color: var(--dark_text);
color: var(--dark_main_text);
}
/* search bar french */
:lang(fr) html.dark-mode #navbar ul#navmenu > span.algolia-autocomplete > input {
background-color: var(--second_dark_bg);
color: var(--dark_text);
color: var(--dark_main_text);
}
/* search bar fixes uz, ru, de, fr */
:lang(uz) span.algolia-autocomplete {
@@ -108,7 +111,7 @@ html.dark-mode #navbar > span.algolia-autocomplete > input::placeholder {
max-width: 100%;
}
html.dark-mode #navbar ul#navmenu > span.algolia-autocomplete > input::placeholder {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode div#overlay {
opacity: 0.5;
@@ -124,13 +127,13 @@ html.dark-mode div#overlay {
/* mobile menu inner links hover */
html.dark-mode div#navbar .menu ul.dropit-submenu a:hover {
background: var(--second_dark_hover);
color: var(--dark_text) !important;
color: var(--dark_main_text) !important;
}
}
html.dark-mode .doc-box.doc-info,
html.dark-mode .doc-box.doc-notice,
html.dark-mode .doc-box.doc-warn {
color: var(--dark_text);
color: var(--dark_main_text);
background: var(--main_dark_bg);
}
html.dark-mode .doc-box.doc-info pre.language-javascript {
@@ -142,14 +145,14 @@ html.dark-mode h3,
html.dark-mode code,
html.dark-mode em,
html.dark-mode strong {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode pre {
background: var(--second_dark_bg);
}
/* index.html */
html.dark-mode #description .express > a {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode #install-command {
background: var(--main_dark_bg);
@@ -158,7 +161,7 @@ html.dark-mode #announcements {
background: var(--main_dark_bg);
}
html.dark-mode #boxes div > h3 {
color: var(--dark_text);
color: var(--dark_main_text);
}
/* basic-routing.htlm */
html.dark-mode [class*='language-'] {
@@ -171,11 +174,11 @@ html.dark-mode .token.operator {
/* debugging.htlm */
html.dark-mode table tr:first-child th {
background-color: var(--second_dark_bg);
color: var(--dark_text);
color: var(--dark_main_text);
}
/* api pages */
html.dark-mode #menu li > * {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode #menu li ul li > em {
color: var(--dark_header_text);
@@ -197,14 +200,14 @@ html.dark-mode .ds-dropdown-menu .ds-dataset-1 {
}
html.dark-mode .ds-dropdown-menu .ds-dataset-1 .ds-suggestion a {
background-color: var(--second_dark_bg);
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode
.ds-dropdown-menu
.ds-dataset-1
.ds-suggestions
.algolia-docsearch-suggestion--category-header {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode
.ds-dropdown-menu
@@ -220,7 +223,7 @@ html.dark-mode
.ds-suggestions
.algolia-docsearch-suggestion--wrapper
.algolia-docsearch-suggestion--title {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode
.ds-dropdown-menu
@@ -228,7 +231,7 @@ html.dark-mode
.ds-suggestions
.algolia-docsearch-suggestion--wrapper
.algolia-docsearch-suggestion--text {
color: var(--dark_text);
color: var(--dark_main_text);
}
html.dark-mode
.ds-dropdown-menu
@@ -242,4 +245,23 @@ html.dark-mode .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--title,
html.dark-mode .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content{
background-color: var(--dark_hover);
}
html.dark-mode .blog-post{
background-color: initial;
border: 1px solid var(--dark_border);
transition: 0.3s;
}
html.dark-mode .blog-post:hover{
background-color: var(--darker_hover);
}
html.dark-mode .blog-title > a{
color: var(--dark_main_text);
}
html.dark-mode .blog-excerpt{
color: var(--dark_bright_text);
}
html.dark-mode #blog-side-menu-container h3 a{
color: var(--dark_header_text);
}
html.dark-mode #blog-side-menu > li > a{
color: var(--dark_inner_text);
}

View File

@@ -739,7 +739,9 @@ footer {
/* secondary menu */
#menu {
#menu,
#tags-side-menu,
#blog-side-menu-container {
position: fixed;
margin: 0;
padding: 0 10px 0 0;
@@ -751,7 +753,23 @@ footer {
overflow-y: auto;
}
#menu em {
#blog-side-menu-container {
max-width: 210px;
}
#blog-side-menu-container li {
max-width: 100%;
margin-bottom: 5px;
}
#blog-side-menu {
list-style: none;
padding: 0;
}
#menu em,
#tags-side-menu em,
#blog-side-menu em{
font-weight: bold;
color: #888;
}
@@ -759,29 +777,53 @@ footer {
#menu li {
list-style: none;
}
#tags-side-menu li {
list-style: none;
font-size: 15px;
font-weight: bold;
}
#menu ul {
#menu ul,
#tags-side-menu ul {
height: 0;
overflow: hidden;
}
#menu ul.active {
#menu ul.active,
#tags-side-menu ul.active {
height: auto;
padding: 0;
}
#menu > li > a {
color: #353535;
#menu > li > a,
#tags-side-menu > li > a,
#blog-side-menu > li > a {
font-weight: bold;
font-size: 15px;
font-size: 13px;
}
#menu ul a {
#blog-side-menu > li > a {
color: #666
}
#blog-side-menu-container > h3 > a {
color: #353535
}
#menu ul a,
#tags-side-menu ul a {
color: #555;
padding-right: 7px;
}
#tags-side-menu ul a{
font-size: 13px;
font-weight:initial;
}
#menu ul a.active {
#menu ul a.active,
#tags-side-menu ul a.active {
color: #259dff;
}
@@ -794,12 +836,12 @@ h2 a {
#q {
display: none;
height: 2.5em;
min-width: 100%;
max-width: 100%;
padding: 5px;
}
.algolia-autocomplete {
min-width: 12em;
max-width: 9em;
top: -0.2em;
margin-right: 3px;
}
@@ -807,6 +849,13 @@ h2 a {
.algolia-autocomplete #q {
display: initial
}
/* search-bar desktop re-sizing */
@media all and (min-width: 950px) {
.algolia-autocomplete {
margin-right:15px;
max-width: 12em;
}
}
/* responsive */
@@ -882,7 +931,9 @@ h2 a {
font-weight: normal;
}
#menu {
#menu,
#tags-side-menu,
#blog-side-menu-container {
display: none;
}
@@ -1195,3 +1246,130 @@ h2 a {
#mw-list ul li {
margin-left: -20px;
}
/* Blog page styles*/
#blog-doc {
margin: 0 10px;
}
#blog-doc:has(> h1#express-blog),
#blog-doc:has(> h1#write-a-blog-post) {
min-height: 300px;
}
#blog-doc .blog-details ~ p > img {
width: 200px;
float: right;
}
#blog-doc p {
font-size: 1.1em;
}
.blog-posts {
display: flex;
flex-direction: column;
row-gap: 10px;
}
.blog-post {
width: 100%;
background-color: #eee;
display: flex;
padding: 10px;
flex-direction: column;
justify-content: space-between;
box-shadow: 2px 3px #E0E0E0;
border-radius: 5px;
border: 1px solid #808080;
transition: 0.1s;
}
.blog-post:hover {
background-color: #D3D3D3;
border: 1px solid #303030;
}
.blog-post img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
}
.blog-post .blog-details {
display: flex;
flex-direction: column;
}
.blog-details div:first-child {
margin-bottom: 5px;
}
.blog-tag {
font-size: 12px;
}
.blog-title {
font-size: 1.3rem;
line-height: 1.5rem;
font-weight: 500;
padding-right: .2em;
}
.blog-title a {
color: #000;
}
.blog-excerpt {
color: initial;
font-size: .75rem;
}
.blog-img {
max-width: 100%;
margin: auto;
}
.blog-author {
font-style: italic;
}
.blog-date {
font-weight: bold;
font-size: 85%;
}
/* mobile-only */
@media (max-width: 500px) {
#blog-doc {
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
padding-right: 10px;
}
#blog-doc .blog-details + p {
display: flex;
flex-direction: column;
align-items: center;
}
#blog-doc .blog-details + p > img {
margin-bottom: 15px;
}
}
/* blog tablet and up*/
@media (min-width: 768px) {
.blog-post {
margin: auto;
}
.blog-tags {
margin-bottom: 20px;
}
.blog-title {
font-size: 1.3rem;
margin-bottom: 20px;
line-height: 1.5rem;
}
.blog-post .blog-details {
display: flex;
flex-direction: row;
margin-left: 1rem;
font-size: 90%;
}
.blog-post .blog-details div:first-child {
margin-right: 20px;
}
.blog-details {
font-size: 1rem;
}
.blog-excerpt {
line-height: initial;
font-size: .85rem;
font-weight: 300;
margin-top: auto;
margin-bottom: 10px;
max-width: 80%;
}
}

28
en/blog/posts.md Normal file
View File

@@ -0,0 +1,28 @@
---
layout: post
title: Express Blog Posts
menu: blog
lang: en
redirect_from: "/blog/posts.html"
---
Want to write a post? See the submission [guidelines.](/en/blog/write-post.html)
{% if site.posts.size != 0 %}
<div class="blog-posts">
{% for post in site.posts %}
<div class="blog-post">
<div class="blog-title">
<a href="{{ post.url }}"> {{ post.title }}</a>
</div>
<div class="blog-details">
<div>By {{ post.author }}</div>
<div >{{ post.date | date:"%b %d, %Y" }}</div>
</div>
<div class="blog-excerpt"> {{post.excerpt | truncate: 240 | markdownify }} </div>
</div>
{% endfor %}
</div>
{% else %}
There are currently no blog posts.
{% endif %}

46
en/blog/write-post.md Normal file
View File

@@ -0,0 +1,46 @@
---
layout: post
title: How to write a blog post
menu: blog
lang: en
redirect_from: "/blog/write.html"
---
![Blogger]({{site.url}}/images/blogger.jpg)
If you have an idea for a blog post, follow these steps to propose it and potentially get it published!
1. ### Propose your post
Before taking the time to write a post, please confirm that we will be able to publish it. We're looking for topics specifically related to Express, and so we want to pre-approve all posts. For the moment, this means we aren't accepting any unsolicited posts. To propose a blog post, [open an issue](https://github.com/expressjs/expressjs.com/issues) entitled `Blog post proposal: <your idea>`.
1. ### Fork the repository
If the Express TC accepts your proposal, start to write your post by forking the [expressjs.com](https://github.com/expressjs/expressjs.com) repository and cloning it to your local machine. Once you open a pull request, you'll be able to preview your post on GitHub. See step six below.
Optional: To run the site locally and preview your post before opening a PR, see the [setup instructions in the README](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#expressjscom).
{: .doc-box .doc-info}
1. ### Create a new file
Create a new file in the `_posts` directory named using following the format: `YYYY-MM-DD-title.md`.
1. ### Add the required front matter
Copy the following front matter, including the dotted lines, and paste it at the top of file you just created. Replace the placeholder values with as desired.
```yaml
---
title: <your-title>
sub_title: <your-optional-sub-title>
date: <date-matching_filename>
tags: <white-space-separated-topics>
author: <your-name>
---
```
2. ### Add your content
Finally, start writing your content below the front matter. Use standard markdown formatting.
1. ### Open a pull request (PR)
Once you open a PR, you will be able to preview your results: There will be a section on the page entitled `Deploy Preview for expressjscom-preview ready!` Click the link to see the site rendered from your fork/branch.
You can use this feature over multiple commits to refine your post by making a `draft` pull request. Once it's ready for review, switch it to a formal PR.

BIN
images/blogger.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

View File

@@ -152,6 +152,11 @@ $(function(){
}
})
$('#tags-side-menu li').on('click', function() {
// Remove prev 'active's
$(this).next().siblings().removeClass('active');
$(this).next().addClass('active')
})
// show mobile menu
$('#nav-button').click(function () {
@@ -173,6 +178,7 @@ $(function(){
$('#guide-menu').dropit({ action: 'click' })
$('#advanced-topics-menu').dropit({ action: 'click' })
$('#resources-menu').dropit({ action: 'click' })
$('#blog-menu').dropit({ action: 'click' })
$('#lb-menu').dropit({ action: 'click' })
$('#changelog-menu').dropit({ action: 'click' })
}
@@ -182,6 +188,7 @@ $(function(){
$('#guide-menu').dropit({ action: 'mouseenter' })
$('#advanced-topics-menu').dropit({ action: 'mouseenter' })
$('#resources-menu').dropit({ action: 'mouseenter' })
$('#blog-menu').dropit({ action: 'mouseenter' })
$('#lb-menu').dropit({ action: 'mouseenter' })
$('#changelog-menu').dropit({ action: 'mouseenter' })
}