I wanted to tweak the dotnetconfig.org site in a few ways, and it turned out that many of the generated files from a docfx build are plain content files that are provided only if your project doesn’t provide them already.
Change default icons
Most docfx sites I see just have the default logo because it’s not
documented (that I could easily find at least) how to change it. Turns out you just have to have your own
logo.svg
(and optionally favicon.ico
) and include it as a resource in your docfx.json:
{
...
"build": {
"resource": [
{
"files": [
"logo.svg",
"favicon.ico"
]
}
]
}
}
Change default styles and scripts
Just like for for icons, you can provide a styles/main.css
file that is automatically referenced. Similarly, you can provide a styles/main.js
to add scripts if needed:
{
// ...
"build": {
"resource": [
{
"files": [
...
"styles/*.css",
"styles/*.js"
]
}
]
}
}
Change included scripts
When I wanted to add my own files outside of the built-in extension points mentioned above, things got trickier. Exporting built-in templates and understanding how the whole template system works seemed overly complicated and overkill for the thing I needed to do. I wanted to add my extended highlightjs language (that’s what docfx uses for highlighting code snippets) to better colorize dotnetconfig, which required including the minified .js to every generated file.
In addition, the version of highlight.js included in docfx is not the latest & gratest, so I wanted to also get a newer one. Basically I need to replace this on every page:
<script type="text/javascript" src="styles/docfx.vendor.js"></script>
<script type="text/javascript" src="styles/docfx.js"></script>
<script type="text/javascript" src="styles/main.js"></script>
</body>
</html>
with
<script type="text/javascript" src="styles/docfx.vendor.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/highlight.min.js"></script>
<script src="https://unpkg.com/highlightjs-dotnetconfig@0.9.1/dist/dotnetconfig.min.js"></script>
<script type="text/javascript" src="styles/docfx.js"></script>
<script type="text/javascript" src="styles/main.js"></script>
</body>
</html>
The docfx templating system allows applying more than one template when building the site, and every template can override what’s included in the previous one by just providing files with the same name and path. Armed with that knowledge, I set to understand how the header and footer of every page is generated by the default template, by just using the CLI:
- Install docfx
> choco install docfx -y
- Export default template
> docfx template export default
- Build a project with that exported template while tweaking things on every build
> docfx build docfx.json -t .\_exported_templates\default --force
- I found that the changes I needed should go in
template\partials\scripts.tmpl.partial
Once happy with the changes, you just create an empty folder structure
matching that and place your updated file there. I placed this “template” alongside my
docfx.json
, which I updated to use it on build:
{
"build": {
...
"template": [
"default",
"./template"
]
}
}
Change included stylesheets
With the learnings from above, it was trivial to find the next part of the template to modify to customize the head element, the head.tmpl.partial. I simply wanted to also reference the latest & greatest CSS from highlight.js, so I added:
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/default.min.css">
with the full file being:
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
<meta name="generator" content="docfx {{_docfxVersion}}">
{{#_description}}<meta name="description" content="{{_description}}">{{/_description}}
<link rel="shortcut icon" href="{{_rel}}{{{_appFaviconPath}}}{{^_appFaviconPath}}favicon.ico{{/_appFaviconPath}}">
<link rel="stylesheet" href="{{_rel}}styles/docfx.vendor.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/default.min.css">
<link rel="stylesheet" href="{{_rel}}styles/docfx.css">
<link rel="stylesheet" href="{{_rel}}styles/main.css">
<meta property="docfx:navrel" content="{{_navRel}}">
<meta property="docfx:tocrel" content="{{_tocRel}}">
{{#_noindex}}<meta name="searchOption" content="noindex">{{/_noindex}}
{{#_enableSearch}}<meta property="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
{{#_enableNewTab}}<meta property="docfx:newtab" content="true">{{/_enableNewTab}}
</head>
Publishing DocFx site from GitHub Actions
I decided to use the project/MSBuild-based approach to build the site, since in my case I only had a single project.
The following MSBuild properties allowed me to tweak the docfx run on build:
<PropertyGroup Label="docfx">
<DocfxConfigFile>../../docs/docfx.json</DocfxConfigFile>
<MetadataOutputFolder>../..</MetadataOutputFolder>
<PreviewOutputFolder>../../docs/_site</PreviewOutputFolder>
<LogFile>$(MSBuildProjectExtensionsPath)/obj/docfx.log</LogFile>
<LogLevel>Info</LogLevel>
<BuildDocFx Condition="'$(BuildDocFx)' == ''">false</BuildDocFx>
</PropertyGroup>
By default I’m not building docs unless BuildDocFx=true
. Trying the output locally is just a matter
of running dotnet build -p:BuildDocFx=true
and then doing a dotnet-serve
in the preview folder.
NOTE: did you know
dotnet-serve
supports configuration via .netconfig files?
Publishing the entire docfx site automatically on pushes to the main
branch
on https://github.com/dotnetconfig/dotnet-config was quite trivial using a simple
GitHub Actions workflow
from that point on:
name: pages
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
- uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.100-preview.7.20366.6
- name: Build 🔧
run: dotnet build -p:BuildDocFx=true
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
GITHUB_TOKEN: $
BRANCH: gh-pages
FOLDER: _site
Note that I’m pushing to the gh-pages
branch, which then is set up in the repository for GH pages,
which coupled with the right CNAME
drives the nice site at https://dotnetconfig.org.
Enjoy!
/kzu dev↻d