Skip to content

Commit 1b05af7

Browse files
authored
Merge pull request #1917 from Simran-B/default-platform
Add support for page.defaultPlatform frontmatter
2 parents 14de288 + 4654635 commit 1b05af7

11 files changed

Lines changed: 131 additions & 18 deletions

File tree

content/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ See the [contributing docs](/CONTRIBUTING.md) for general information about work
2020
- [`showMiniToc`](#showminitoc)
2121
- [`miniTocMaxHeadingLevel`](#minitocmaxheadinglevel)
2222
- [`allowTitleToDifferFromFilename`](#allowtitletodifferfromfilename)
23+
- [`defaultPlatform`](#defaultplatform)
2324
- [Escaping single quotes](#escaping-single-quotes)
2425
- [Autogenerated mini TOCs](#autogenerated-mini-tocs)
2526
- [Versioning](#versioning)
@@ -172,6 +173,18 @@ featuredLinks:
172173
- Type: `Array`, items are objects `{ href: string, title: string, date: 'YYYY-MM-DD' }`
173174
- Optional.
174175

176+
### `defaultPlatform`
177+
178+
- Purpose: Override the initial platform selection for a page. If this frontmatter is omitted, then the platform-specific content matching the reader's operating system is shown by default. This behavior can be changed for individual pages, for which a manual selection is more reasonable. For example, most GitHub Actions runners use Linux and their operating system is independent of the reader's operating system.
179+
- Type: `String`, one of: `mac`, `windows`, `linux`.
180+
- Optional.
181+
182+
Example:
183+
184+
```yaml
185+
defaultPlatform: linux
186+
```
187+
175188
### Escaping single quotes
176189

177190
If you see two single quotes in a row (`''`) in YML frontmatter where you might expect to see one (`'`), this is the YML-preferred way to escape a single quote. From [the YAML spec](https://yaml.org/spec/history/2001-12-10.html):

content/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ redirect_from:
66
versions:
77
free-pro-team: '*'
88
enterprise-server: '>=2.22'
9+
defaultPlatform: linux
910
---
1011

1112
{% data reusables.actions.enterprise-beta %}

content/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ redirect_from:
88
versions:
99
free-pro-team: '*'
1010
enterprise-server: '>=2.22'
11+
defaultPlatform: linux
1112
---
1213

1314
{% data reusables.actions.enterprise-beta %}

contributing/content-markup-reference.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ For information on when to use callout tags, see the [style guide](content-style
3838

3939
To render syntax highlighting in command line instructions, we use triple backticks followed by the term `shell`.
4040

41-
### Usage
42-
43-
```shell
44-
git init <em>YOUR_REPO</em>
41+
### Usage
42+
43+
```shell
44+
git init <em>YOUR_REPO</em>
4545
```
4646

4747
This syntax highlighting renders light text on a dark background, and should be reserved for command line instructions.
@@ -62,9 +62,11 @@ Octicons are icons used across GitHub’s interface. We reference Octicons when
6262

6363
### Usage
6464

65-
`{% octicon "<name of octicon>" %}`
66-
`{% octicon "plus" %}`
67-
`{% octicon "plus" aria-label="The plus icon" %}`
65+
```
66+
{% octicon "<name of octicon>" %}
67+
{% octicon "plus" %}
68+
{% octicon "plus" aria-label="The plus icon" %}
69+
```
6870

6971
## Operating system tags
7072

@@ -79,27 +81,24 @@ These instructions are pertinent to Mac users.
7981
8082
{% endmac %}
8183
```
84+
8285
```
8386
{% windows %}
8487
8588
These instructions are pertinent to Windows users.
8689
8790
{% endwindows %}
8891
```
92+
8993
```
9094
{% linux %}
9195
9296
These instructions are pertinent to Linux users.
9397
9498
{% endlinux %}
9599
```
96-
```
97-
{% all %}
98100

99-
Though rare, these instructions are pertinent to any other operating system.
100-
101-
{% endall %}
102-
```
101+
You can define a default platform in the frontmatter, see the [content README](../content/README.md#defaultplatform).
103102

104103
## Reusable and variable strings of text
105104

includes/article.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ <h1 class="border-bottom-0">{{ page.title }}</h1>
2929
{% endif %}
3030

3131
{% if page.includesPlatformSpecificContent %}
32-
<nav class="UnderlineNav my-3">
32+
<nav class="UnderlineNav my-3"
33+
{%- if page.defaultPlatform %} data-default-platform="{{ page.defaultPlatform }}"{% endif %}>
3334
<div class="UnderlineNav-body">
3435
<a href="#" class="UnderlineNav-item platform-switcher" data-platform="mac">Mac</a>
3536
<a href="#" class="UnderlineNav-item platform-switcher" data-platform="windows">Windows</a>
3637
<a href="#" class="UnderlineNav-item platform-switcher" data-platform="linux">Linux</a>
37-
<a href="#" class="UnderlineNav-item platform-switcher" data-platform="all">All</a>
3838
</div>
3939
</nav>
4040
{% endif %}

javascripts/display-platform-specific-content.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const detectedPlatforms = new Set()
55
// Emphasize content for the visitor's OS (inferred from user agent string)
66

77
export default function displayPlatformSpecificContent () {
8-
let platform = getPlatformFromUserAgent()
8+
let platform = getDefaultPlatform() || getPlatformFromUserAgent()
99

1010
// adjust platform names to fit existing mac/windows/linux scheme
1111
if (!platform) platform = 'mac' // default to 'mac' on mobile
@@ -78,6 +78,11 @@ function detectPlatforms (el) {
7878
})
7979
}
8080

81+
function getDefaultPlatform () {
82+
const el = document.querySelector('[data-default-platform]')
83+
if (el) return el.dataset.defaultPlatform
84+
}
85+
8186
function switcherLinks () {
8287
return Array.from(document.querySelectorAll('a.platform-switcher'))
8388
}

lib/frontmatter.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ const schema = {
100100
},
101101
interactive: {
102102
type: 'boolean'
103+
},
104+
// Platform-specific content preference
105+
defaultPlatform: {
106+
type: 'string',
107+
enum: ['mac', 'windows', 'linux']
103108
}
104109
}
105110
}

lib/page.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class Page {
197197
const $ = cheerio.load(html)
198198

199199
// set a flag so layout knows whether to render a mac/windows/linux switcher element
200-
this.includesPlatformSpecificContent = $('[class^="platform-"], .mac, .windows, .linux, .all').length > 0
200+
this.includesPlatformSpecificContent = $('[class^="platform-"], .mac, .windows, .linux').length > 0
201201

202202
// rewrite asset paths to s3 if it's a dotcom article on any GHE version
203203
// or if it's an enterprise article on any GHE version EXCEPT latest version

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
"prebrowser-test": "npm run build",
161161
"browser-test": "start-server-and-test browser-test-server 4001 browser-test-tests",
162162
"browser-test-server": "cross-env NODE_ENV=production ENABLED_LANGUAGES='en,ja' PORT=4001 node server.js",
163-
"browser-test-tests": "BROWSER=1 jest tests/browser/browser.js",
163+
"browser-test-tests": "cross-env BROWSER=1 jest tests/browser/browser.js",
164164
"sync-search": "start-server-and-test sync-search-server 4002 sync-search-indices",
165165
"sync-search-dry-run": "DRY_RUN=1 npm run sync-search",
166166
"sync-search-server": "cross-env NODE_ENV=production PORT=4002 node server.js",

tests/browser/browser.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,80 @@ async function getLocationObject (page) {
172172
})
173173
return JSON.parse(location)
174174
}
175+
176+
describe('platform specific content', () => {
177+
// from tests/javascripts/user-agent.js
178+
const userAgents = [
179+
{ name: 'Mac', id: 'mac', ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9' },
180+
{ name: 'Windows', id: 'windows', ua: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36' },
181+
{ name: 'Linux', id: 'linux', ua: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1' }
182+
]
183+
const linuxUserAgent = userAgents[2]
184+
const pageWithSwitcher = 'http://localhost:4001/en/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners'
185+
const pageWithoutSwitcher = 'http://localhost:4001/en/github/using-git'
186+
const pageWithDefaultPlatform = 'http://localhost:4001/en/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service'
187+
188+
it('should have a platform switcher', async () => {
189+
await page.goto(pageWithSwitcher)
190+
const nav = await page.$$('nav.UnderlineNav')
191+
const switches = await page.$$('a.platform-switcher')
192+
const selectedSwitch = await page.$$('a.platform-switcher.selected')
193+
expect(nav).toHaveLength(1)
194+
expect(switches.length).toBeGreaterThan(1)
195+
expect(selectedSwitch).toHaveLength(1)
196+
})
197+
198+
it('should NOT have a platform switcher', async () => {
199+
await page.goto(pageWithoutSwitcher)
200+
const nav = await page.$$('nav.UnderlineNav')
201+
const switches = await page.$$('a.platform-switcher')
202+
const selectedSwitch = await page.$$('a.platform-switcher.selected')
203+
expect(nav).toHaveLength(0)
204+
expect(switches).toHaveLength(0)
205+
expect(selectedSwitch).toHaveLength(0)
206+
})
207+
208+
it('should detect platform from user agent', async () => {
209+
for (const agent of userAgents) {
210+
await page.setUserAgent(agent.ua)
211+
await page.goto(pageWithSwitcher)
212+
const selectedPlatformElement = await page.waitForSelector('a.platform-switcher.selected')
213+
const selectedPlatform = await page.evaluate(el => el.textContent, selectedPlatformElement)
214+
expect(selectedPlatform).toBe(agent.name)
215+
}
216+
})
217+
218+
it('should prefer defaultPlatform from frontmatter', async () => {
219+
for (const agent of userAgents) {
220+
await page.setUserAgent(agent.ua)
221+
await page.goto(pageWithDefaultPlatform)
222+
const defaultPlatform = await page.$eval('[data-default-platform]', el => el.dataset.defaultPlatform)
223+
const selectedPlatformElement = await page.waitForSelector('a.platform-switcher.selected')
224+
const selectedPlatform = await page.evaluate(el => el.textContent, selectedPlatformElement)
225+
expect(defaultPlatform).toBe(linuxUserAgent.id)
226+
expect(selectedPlatform).toBe(linuxUserAgent.name)
227+
}
228+
})
229+
230+
it('should show the content for the selected platform only', async () => {
231+
await page.goto(pageWithSwitcher)
232+
233+
const platforms = ['mac', 'windows', 'linux']
234+
for (const platform of platforms) {
235+
await page.click(`.platform-switcher[data-platform="${platform}"]`)
236+
237+
// content for selected platform is expected to become visible
238+
await page.waitForSelector(`.extended-markdown.${platform}`, { visible: true, timeout: 3000 })
239+
240+
// only a single tab should be selected
241+
const selectedSwitch = await page.$$('a.platform-switcher.selected')
242+
expect(selectedSwitch).toHaveLength(1)
243+
244+
// content for NOT selected platforms is expected to become hidden
245+
const otherPlatforms = platforms.filter(e => e !== platform)
246+
for (const other of otherPlatforms) {
247+
await page.waitForSelector(`.extended-markdown.${other}`, { hidden: true, timeout: 3000 })
248+
}
249+
}
250+
})
251+
})

0 commit comments

Comments
 (0)