Branch was updated using the 'autoupdate branch' Actions workflow.
This commit is contained in:
@@ -46,29 +46,4 @@ versions:
|
||||
<!-- {% link_with_intro /creating-actions %} -->
|
||||
<!-- {% link_with_intro /using-github-hosted-runners %} -->
|
||||
<!-- {% link_with_intro /hosting-your-own-runners %} -->
|
||||
<!-- {% link_with_intro /reference %} -->
|
||||
|
||||
<!-- Code examples -->
|
||||
{% assign actionsCodeExamples = site.data.variables.action_code_examples %}
|
||||
{% if actionsCodeExamples %}
|
||||
<div class="my-6 pt-6">
|
||||
<h2 class="mb-2 font-mktg h1">Code examples</h2>
|
||||
|
||||
<div class="pr-lg-3 mb-5 mt-3">
|
||||
<input class="js-filter-card-filter input-lg py-2 px-3 col-12 col-lg-8 form-control" placeholder="Search code examples" type="search" autocomplete="off" aria-label="Search code examples"/>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-wrap gutter">
|
||||
{% render code-example-card for actionsCodeExamples as example %}
|
||||
</div>
|
||||
|
||||
<button class="js-filter-card-show-more btn btn-outline float-right" data-js-filter-card-max="6">Show more {% octicon "arrow-right" %}</button>
|
||||
|
||||
<div class="js-filter-card-no-results d-none py-4 text-center color-text-secondary font-mktg">
|
||||
<div class="mb-3">{% octicon "search" width="24" %}</div>
|
||||
<h3 class="text-normal">Sorry, there is no result for <strong class="js-filter-card-value"></strong></h3>
|
||||
<p class="my-3 f4">It looks like we don't have an example that fits your filter.<br>Try another filter or add your code example</p>
|
||||
<a href="https://github.com/github/docs/blob/main/data/variables/action_code_examples.yml">Learn how to add a code example {% octicon "arrow-right" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- {% link_with_intro /reference %} -->
|
||||
@@ -34,24 +34,3 @@ versions:
|
||||
<!-- {% link_with_intro /discussions-guides %} -->
|
||||
<!-- {% link_with_intro /collaborating-with-your-community-using-discussions %} -->
|
||||
<!-- {% link_with_intro /managing-discussions-for-your-community %} -->
|
||||
|
||||
<!-- Community examples -->
|
||||
{% assign discussionsCommunityExamples = site.data.variables.discussions_community_examples %}
|
||||
{% if discussionsCommunityExamples %}
|
||||
<div class="my-6 pt-6">
|
||||
<h2 class="mb-2 font-mktg h1">Communities using discussions</h2>
|
||||
|
||||
<div class="d-flex flex-wrap gutter">
|
||||
{% render discussions-community-card for discussionsCommunityExamples as example %}
|
||||
</div>
|
||||
{% if discussionsCommunityExamples.length > 6 %}
|
||||
<button class="js-filter-card-show-more btn btn-outline float-right" data-js-filter-card-max="6">Show more {% octicon "arrow-right" %}</button>
|
||||
{% endif %}
|
||||
<div class="js-filter-card-no-results d-none py-4 text-center color-text-secondary font-mktg">
|
||||
<div class="mb-3">{% octicon "search" width="24" %}</div>
|
||||
<h3 class="text-normal">Sorry, there is no result for <strong class="js-filter-card-value"></strong></h3>
|
||||
<p class="my-3 f4">It looks like we don't have an example that fits your filter.<br>Try another filter or add your code example</p>
|
||||
<a href="https://github.com/github/docs/blob/main/data/variables/discussions_community_examples.yml">Add your community {% octicon "arrow-right" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
11
data/ui.yml
11
data/ui.yml
@@ -140,6 +140,16 @@ product_landing:
|
||||
quick_start: Quickstart
|
||||
reference_guides: Reference guides
|
||||
overview: Overview
|
||||
code_examples: Code examples
|
||||
search_code_examples: Search code examples
|
||||
show_more: Show more
|
||||
sorry: Sorry, there is no result for
|
||||
no_example: It looks like we don't have an example that fits your filter.
|
||||
try_another: Try another filter or add your code example.
|
||||
no_result: Sorry, there is no guide that match your filter.
|
||||
learn: Learn how to add a code example
|
||||
communities_using_discussions: Communities using discussions
|
||||
add_your_community: Add your community
|
||||
product_sublanding:
|
||||
start: Start
|
||||
start_path: Start path
|
||||
@@ -149,7 +159,6 @@ product_sublanding:
|
||||
more_guides: more guides
|
||||
load_more: Load more guides
|
||||
all_guides: 'All {{ productMap[currentProduct].name }} guides'
|
||||
no_result: Sorry, there is no guide that match your filter.
|
||||
filters:
|
||||
type: Type
|
||||
topic: Topic
|
||||
|
||||
20
includes/code-examples.html
Normal file
20
includes/code-examples.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="my-6 pt-6">
|
||||
<h2 class="mb-2 font-mktg h1">{% data ui.product_landing.code_examples %}</h2>
|
||||
|
||||
<div class="pr-lg-3 mb-5 mt-3">
|
||||
<input class="js-filter-card-filter input-lg py-2 px-3 col-12 col-lg-8 form-control" placeholder="{% data ui.product_landing.search_code_examples %}" type="search" autocomplete="off" aria-label="Search code examples"/>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-wrap gutter">
|
||||
{% render code-example-card for productCodeExamples as example %}
|
||||
</div>
|
||||
|
||||
<button class="js-filter-card-show-more btn btn-outline float-right" data-js-filter-card-max="6">{% data ui.product_landing.show_more %} {% octicon "arrow-right" %}</button>
|
||||
|
||||
<div class="js-filter-card-no-results d-none py-4 text-center color-text-secondary font-mktg">
|
||||
<div class="mb-3">{% octicon "search" width="24" %}</div>
|
||||
<h3 class="text-normal">{% data ui.product_landing.sorry %} <strong class="js-filter-card-value"></strong></h3>
|
||||
<p class="my-3 f4">{% data ui.product_landing.no_result %}<br>{% data ui.product_landing.try_another %}</p>
|
||||
<a href="https://github.com/github/docs/blob/main/data/variables/actions_code_examples.yml">{% data ui.product_landing.learn %} {% octicon "arrow-right" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
16
includes/community-examples.html
Normal file
16
includes/community-examples.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="my-6 pt-6">
|
||||
<h2 class="mb-2 font-mktg h1">{% data ui.product_landing.communities_using_discussions %}</h2>
|
||||
|
||||
<div class="d-flex flex-wrap gutter">
|
||||
{% render discussions-community-card for productCommunityExamples as example %}
|
||||
</div>
|
||||
{% if productCommunityExamples.length > 6 %}
|
||||
<button class="js-filter-card-show-more btn btn-outline float-right" data-js-filter-card-max="6">{% data ui.product_landing.show_more %} {% octicon "arrow-right" %}</button>
|
||||
{% endif %}
|
||||
<div class="js-filter-card-no-results d-none py-4 text-center color-text-secondary font-mktg">
|
||||
<div class="mb-3">{% octicon "search" width="24" %}</div>
|
||||
<h3 class="text-normal">{% data ui.product_landing.sorry %} <strong class="js-filter-card-value"></strong></h3>
|
||||
<p class="my-3 f4">{% data ui.product_landing.no_example %} <br>{% data ui.product_landing.try_another %}</p>
|
||||
<a href="https://github.com/github/docs/blob/main/data/variables/discussions_community_examples.yml">{% data ui.product_landing.add_your_community %} {% octicon "arrow-right" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -19,13 +19,14 @@
|
||||
{% capture fullPathToCategory %}{{category[1].href}}{% endcapture %}
|
||||
|
||||
<li class="sidebar-category py-1 {% if breadcrumbs.category.href == category[1].href %}active {% if currentPath == fullPathToCategory %}is-current-page {% endif %}{% endif %}{% if category[1].standalone %}standalone-category{% endif %}">
|
||||
{% if category[1].shortTitle %}{% assign categoryTitle = category[1].shortTitle %}{% else %}{% assign categoryTitle = category[1].title %}{% endif %}
|
||||
{% if category[1].standalone %}
|
||||
<a href="{{fullPathToCategory}}" class="pl-4 pr-2 py-2 f6 text-uppercase d-block flex-auto mr-3">{{ category[1].title }}</a>
|
||||
<a href="{{fullPathToCategory}}" class="pl-4 pr-2 py-2 f6 text-uppercase d-block flex-auto mr-3">{{ categoryTitle }}</a>
|
||||
{% else %}
|
||||
<details class="dropdown-withArrow details details-reset" {% if breadcrumbs.category.href == category[1].href or forloop.index < 4 %}open{% endif %}>
|
||||
<summary>
|
||||
<div class="d-flex flex-justify-between">
|
||||
<a href="{{fullPathToCategory}}" class="pl-4 pr-2 py-2 f6 text-uppercase d-block flex-auto mr-3">{{ category[1].title }}</a>
|
||||
<a href="{{fullPathToCategory}}" class="pl-4 pr-2 py-2 f6 text-uppercase d-block flex-auto mr-3">{{ categoryTitle }}</a>
|
||||
{% if breadcrumbs.category.href == category[1].href or forloop.index < 4 %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="octicon flex-shrink-0 arrow mr-3" style="margin-top:7px" viewBox="0 0 16 16" width="16" height="16"> <path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></svg>
|
||||
{% endif %}
|
||||
@@ -39,16 +40,18 @@
|
||||
{% for maptopic in category[1].maptopics %}
|
||||
{% unless maptopic[1].hidden %}
|
||||
{% capture fullPathToMaptopic %}{{maptopic[1].href}}{% endcapture %}
|
||||
{% if maptopic[1].shortTitle %}{% assign maptopicTitle = maptopic[1].shortTitle %}{% else %}{% assign maptopicTitle = maptopic[1].title %}{% endif %}
|
||||
|
||||
<li class="sidebar-maptopic {% if breadcrumbs.maptopic.href == maptopic[1].href %}active {% if currentPath == fullPathToMaptopic %}is-current-page{% endif %}{% endif %}">
|
||||
<a href="{{fullPathToMaptopic}}" class="pl-4 pr-5 py-2">{{ maptopic[1].title }}</a>
|
||||
<a href="{{fullPathToMaptopic}}" class="pl-4 pr-5 py-2">{{ maptopicTitle }}</a>
|
||||
<ul class="sidebar-articles my-2">
|
||||
{% for article in maptopic[1].articles %}
|
||||
{% unless article[1].hidden %}
|
||||
{% capture fullPathToArticle %}{{article[1].href}}{% endcapture %}
|
||||
{% if article[1].shortTitle %}{% assign articleTitle = article[1].shortTitle %}{% else %}{% assign articleTitle = article[1].title %}{% endif %}
|
||||
|
||||
<li class="sidebar-article {% if breadcrumbs.article.href == article[1].href %}active {% if currentPath == fullPathToArticle %}is-current-page{% endif %}{% endif %}">
|
||||
<a href="{{fullPathToArticle}}" class="pl-6 pr-5 py-1{% if forloop.last %} pb-2{% endif %}">{{ article[1].title }}</a>
|
||||
<a href="{{fullPathToArticle}}" class="pl-6 pr-5 py-1{% if forloop.last %} pb-2{% endif %}">{{ articleTitle }}</a>
|
||||
</li>
|
||||
{% endunless %}
|
||||
{% endfor %}
|
||||
@@ -63,8 +66,9 @@
|
||||
{% for article in category[1].articles %}
|
||||
{% unless article[1].hidden %}
|
||||
{% capture fullPathToArticle %}{{article[1].href}}{% endcapture %}
|
||||
{% if article[1].shortTitle %}{% assign articleTitle = article[1].shortTitle %}{% else %}{% assign articleTitle = article[1].title %}{% endif %}
|
||||
<li class="sidebar-article {% if breadcrumbs.article.href == article[1].href %}active {% if currentPath == fullPathToArticle %}is-current-page{% endif %}{% endif %}">
|
||||
<a href="{{fullPathToArticle}}" class="pl-4 pr-5 py-1{% if forloop.last %} pb-2{% endif %}">{{ article[1].title }}</a>
|
||||
<a href="{{fullPathToArticle}}" class="pl-4 pr-5 py-1{% if forloop.last %} pb-2{% endif %}">{{ articleTitle }}</a>
|
||||
</li>
|
||||
{% endunless %}
|
||||
{% endfor %}
|
||||
|
||||
@@ -117,6 +117,14 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if productCodeExamples %}
|
||||
{% include code-examples %}
|
||||
{% endif %}
|
||||
|
||||
{% if productCommunityExamples %}
|
||||
{% include community-examples %}
|
||||
{% endif %}
|
||||
|
||||
{{ renderedPage }}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,18 +2,19 @@ const flat = require('flat')
|
||||
const renderContent = require('./render-content')
|
||||
const delimiter = '#'
|
||||
|
||||
// render localized and product-version-aware page title
|
||||
// note this only supports titles with liquid, not short titles
|
||||
// render localized and product-version-aware page title or shortTitle
|
||||
|
||||
module.exports = async function siteTreeTitles (siteTree, siteData) {
|
||||
// use a non-period delimiter because versions contain periods (like 2.19)
|
||||
const flatTree = flat(siteTree, { delimiter: delimiter })
|
||||
|
||||
const titlesWithLiquid = Object.entries(flatTree)
|
||||
.filter(([path, title]) => path.endsWith('title') && title.includes('{'))
|
||||
.filter(([path, shortOrLongTitle]) => path.endsWith('itle') && shortOrLongTitle && shortOrLongTitle.includes('{'))
|
||||
|
||||
await Promise.all(titlesWithLiquid.map(async ([path, title]) => {
|
||||
path = path.replace(`${delimiter}title`, '') // ignore the `title` path part for now
|
||||
await Promise.all(titlesWithLiquid.map(async ([path, shortOrLongTitle]) => {
|
||||
const isShortTitle = /shortTitle$/.test(path)
|
||||
|
||||
path = path.replace(`${delimiter}(shortT|t)itle`, '') // ignore the `title` path part for now
|
||||
|
||||
// derive values from path parts
|
||||
const [
|
||||
@@ -31,29 +32,39 @@ module.exports = async function siteTreeTitles (siteTree, siteData) {
|
||||
|
||||
// create context object for rendering of dynamic liquid data in page titles
|
||||
const ctx = {
|
||||
page: { version },
|
||||
currentVersion: version,
|
||||
site: siteData[languageCode].site
|
||||
}
|
||||
|
||||
const renderedTitle = await renderContent(title, ctx, { textOnly: true })
|
||||
const renderedShortOrLongTitle = await renderContent(shortOrLongTitle, ctx, { textOnly: true })
|
||||
|
||||
// no product titles have liquid because we get them from lib/all-products.js
|
||||
// so we can assume all titles processed here will be either a category, maptopic, or article
|
||||
// we can also assume a category value will exist for any of these
|
||||
const currentCategory = siteTree[languageCode][version][products][product][categories][category]
|
||||
|
||||
if (!maptopic) currentCategory.title = renderedTitle
|
||||
if (!maptopic) {
|
||||
isShortTitle
|
||||
? currentCategory.shortTitle = renderedShortOrLongTitle
|
||||
: currentCategory.title = renderedShortOrLongTitle
|
||||
}
|
||||
|
||||
let currentMaptopic
|
||||
if (maptopic) {
|
||||
currentMaptopic = currentCategory[maptopics][maptopic]
|
||||
if (!article) currentMaptopic.title = renderedTitle
|
||||
if (!article) {
|
||||
isShortTitle
|
||||
? currentMaptopic.shortTitle = renderedShortOrLongTitle
|
||||
: currentMaptopic.title = renderedShortOrLongTitle
|
||||
}
|
||||
}
|
||||
|
||||
let currentArticle
|
||||
if (article) {
|
||||
currentArticle = currentMaptopic[articles][article]
|
||||
currentArticle.title = renderedTitle
|
||||
isShortTitle
|
||||
? currentArticle.shortTitle = renderedShortOrLongTitle
|
||||
: currentArticle.title = renderedShortOrLongTitle
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ function buildCategoriesTree (tocItems, versionedProductHref, pageMap, redirects
|
||||
if (!page) return
|
||||
if (!getApplicableVersions(page.versions).includes(version)) return
|
||||
|
||||
category.title = page.shortTitle || page.title
|
||||
category.title = page.title
|
||||
category.shortTitle = page.shortTitle
|
||||
|
||||
// support standalone pages at the category level, like actions/quickstart.md
|
||||
if (!page.tocItems) {
|
||||
@@ -157,7 +158,8 @@ function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects,
|
||||
if (!page) return
|
||||
if (!getApplicableVersions(page.versions).includes(version)) return
|
||||
|
||||
article.title = page.shortTitle || page.title
|
||||
article.title = page.title
|
||||
article.shortTitle = page.shortTitle
|
||||
article.hidden = page.hidden
|
||||
|
||||
articleTree[article.href] = article
|
||||
|
||||
@@ -1,65 +1,54 @@
|
||||
// This middleware serves a file that's used by the GitHub support team
|
||||
// to quickly search for Help articles by title and insert the link to
|
||||
// the article into a reply to a customer.
|
||||
const path = require('path')
|
||||
const matter = require('gray-matter')
|
||||
const readFileAsync = require('../lib/readfile-async')
|
||||
const dotcomDir = path.join(__dirname, '../content/github')
|
||||
const dotcomIndex = path.join(dotcomDir, 'index.md')
|
||||
const linkRegex = /{% (?:topic_)?link_in_list ?\/(.*?) ?%}/g
|
||||
|
||||
module.exports = async function categoriesForSupportTeam (req, res, next) {
|
||||
if (req.path !== '/categories.json') return next()
|
||||
const categories = await generateCategories()
|
||||
return res.json(categories)
|
||||
}
|
||||
|
||||
async function generateCategories () {
|
||||
// get links included in dotcom index page.
|
||||
// each link corresponds to a dotcom subdirectory
|
||||
// example: getting-started-with-github
|
||||
const links = getLinks(await readFileAsync(dotcomIndex, 'utf8'))
|
||||
|
||||
// get links included in each subdir's index page
|
||||
// these are links to articles
|
||||
const categories = await Promise.all(links.map(async link => {
|
||||
const category = {}
|
||||
const indexPath = getPath(link, 'index')
|
||||
const indexContents = await readFileAsync(indexPath, 'utf8')
|
||||
const { data, content } = matter(indexContents)
|
||||
|
||||
// get name from title frontmatter
|
||||
category.name = data.title
|
||||
|
||||
// get child article links
|
||||
const articleLinks = getLinks(content)
|
||||
|
||||
category.published_articles = (await Promise.all(articleLinks.map(async articleLink => {
|
||||
// get title from frontmatter
|
||||
const articlePath = getPath(link, articleLink)
|
||||
const articleContents = await readFileAsync(articlePath, 'utf8')
|
||||
const { data } = matter(articleContents)
|
||||
|
||||
// do not include map topics in list of published articles
|
||||
if (data.mapTopic) return
|
||||
|
||||
return {
|
||||
title: data.title,
|
||||
slug: articleLink
|
||||
}
|
||||
}))).filter(Boolean)
|
||||
|
||||
return category
|
||||
}))
|
||||
|
||||
return categories
|
||||
}
|
||||
|
||||
function getLinks (contents) {
|
||||
return contents.match(linkRegex)
|
||||
.map(link => link.match(linkRegex.source)[1])
|
||||
}
|
||||
|
||||
function getPath (link, filename) {
|
||||
return path.join(dotcomDir, link, `${filename}.md`)
|
||||
const englishSiteTree = req.context.siteTree.en
|
||||
|
||||
const allCategories = []
|
||||
|
||||
Object.keys(englishSiteTree).forEach(version => {
|
||||
const versionedProductsTree = englishSiteTree[version].products
|
||||
|
||||
Object.values(versionedProductsTree).forEach(productObj => {
|
||||
if (productObj.id === 'early-access') return
|
||||
if (productObj.external) return
|
||||
|
||||
Object.values(productObj.categories).forEach(categoryObj => {
|
||||
const articlesArry = []
|
||||
|
||||
if (categoryObj.maptopics) {
|
||||
Object.values(categoryObj.maptopics).forEach(maptopicObj => {
|
||||
Object.values(maptopicObj.articles).forEach(articleObj => {
|
||||
articlesArry.push({
|
||||
title: articleObj.title,
|
||||
slug: path.basename(articleObj.href)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (categoryObj.standalone) {
|
||||
articlesArry.push({
|
||||
title: categoryObj.title,
|
||||
slug: path.basename(categoryObj.href)
|
||||
})
|
||||
}
|
||||
|
||||
if (categoryObj.articles) {
|
||||
Object.values(categoryObj.articles).forEach(articleObj => {
|
||||
articlesArry.push({
|
||||
title: articleObj.title,
|
||||
slug: path.basename(articleObj.href)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
allCategories.push({
|
||||
name: categoryObj.title,
|
||||
published_articles: articlesArry
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
return res.json(allCategories)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,11 @@ module.exports = async function contextualize (req, res, next) {
|
||||
req.context.siteTree = siteTree
|
||||
req.context.pages = pageMap
|
||||
|
||||
if (productMap[req.context.currentProduct]) {
|
||||
req.context.productCodeExamples = req.context.site.data.variables[`${productMap[req.context.currentProduct].id}_code_examples`]
|
||||
req.context.productCommunityExamples = req.context.site.data.variables[`${productMap[req.context.currentProduct].id}_community_examples`]
|
||||
}
|
||||
|
||||
// JS + CSS asset paths
|
||||
req.context.builtAssets = builtAssets
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ module.exports = function (app) {
|
||||
app.use(asyncMiddleware(instrument('./archived-enterprise-versions')))
|
||||
app.use(instrument('./robots'))
|
||||
app.use(/(\/.*)?\/early-access$/, instrument('./contextualizers/early-access-links'))
|
||||
app.use(asyncMiddleware(instrument('./categories-for-support-team')))
|
||||
app.use('/categories.json', asyncMiddleware(instrument('./categories-for-support-team')))
|
||||
app.use(instrument('./loaderio-verification'))
|
||||
app.get('/_500', asyncMiddleware(instrument('./trigger-error')))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user