mirror of
https://github.com/hugo-fixit/FixIt.git
synced 2026-08-24 23:38:56 +00:00
feat(link): add link_guard front matter and support for friend links
This commit is contained in:
@@ -7,6 +7,11 @@ categories:
|
||||
- Markdown
|
||||
tags:
|
||||
- Link
|
||||
link_guard:
|
||||
enable: true
|
||||
# mode: redirect
|
||||
allow_domains:
|
||||
- demo.fixit.lruihao.cn
|
||||
---
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,10 @@
|
||||
font-family: fixit-var(code-font-family);
|
||||
font-size: 0.875rem;
|
||||
line-height: 1rem;
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@include user-select(text);
|
||||
@include border-radius;
|
||||
}
|
||||
|
||||
@@ -80,4 +83,13 @@
|
||||
background-color: fixit-var(primary);
|
||||
border-color: fixit-var(primary);
|
||||
}
|
||||
|
||||
@include media('xs') {
|
||||
padding: 1rem;
|
||||
|
||||
.cancel-btn,
|
||||
.confirm-btn {
|
||||
flex: 1 1 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,24 +47,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media('xs') {
|
||||
#link-guard-dialog {
|
||||
width: calc(100% - 2rem);
|
||||
|
||||
.guard-content {
|
||||
padding: 1rem;
|
||||
|
||||
.actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.cancel-btn,
|
||||
.confirm-btn {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#content-link {
|
||||
margin: auto 0;
|
||||
align-self: center;
|
||||
|
||||
.card {
|
||||
width: MIN(600px, calc(100% - 2rem));
|
||||
@@ -8,8 +8,7 @@
|
||||
@include link-guard-content;
|
||||
|
||||
@include media('xs') {
|
||||
margin-inline: 0;
|
||||
padding: 1rem;
|
||||
width: MIN(600px, 100%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1143,7 +1143,8 @@ blackList = []
|
||||
# whether to add external Icon for external links automatically
|
||||
external_icon = true
|
||||
|
||||
# external link guard config
|
||||
# External link guard config
|
||||
# per-page override via front matter: link_guard (bool/object)
|
||||
[params.link.guard]
|
||||
enable = false
|
||||
# external link guard mode, available modes: ["modal", "redirect"]
|
||||
@@ -1282,6 +1283,8 @@ linkToEdit = true
|
||||
# FixIt 0.3.0 | NEW whether to show link to report issue for the post
|
||||
linkToReport = true
|
||||
# FixIt 0.3.20 | NEW whether to show link to view the post in VSCode
|
||||
# [todo] (string) migrate to link_to_editor config in the future
|
||||
# to support more editors (vscode://, trae://, etc.)
|
||||
linkToVscode = true
|
||||
# FixIt 0.3.10 | CHANGED Page style ["narrow", "normal", "wide", ...]
|
||||
pageStyle = "normal"
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{{- with dict "Path" $destination | partial "function/resource.html" -}}
|
||||
{{- $destination = .RelPermalink -}}
|
||||
{{- end -}}
|
||||
{{- $options := dict "Destination" $destination "Title" .Title "Content" .Text -}}
|
||||
{{- $options := dict "Destination" $destination "Title" .Title "Content" .Text "Page" .Page -}}
|
||||
{{- partial "plugin/link.html" $options -}}
|
||||
|
||||
@@ -66,7 +66,11 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Link Guard Dialog */ -}}
|
||||
{{- if .Site.Params.link.guard.enable -}}
|
||||
{{- $linkGuard := .Site.Params.link.guard -}}
|
||||
{{- with .Params.link_guard -}}
|
||||
{{- $linkGuard = (cond (reflect.IsMap .) . (dict "enable" .)) | merge $linkGuard -}}
|
||||
{{- end -}}
|
||||
{{- if $linkGuard.enable | and (eq $linkGuard.mode "modal") -}}
|
||||
<dialog id="link-guard-dialog" aria-labelledby="link-guard-dialog-title" role="dialog">
|
||||
<div class="guard-content">
|
||||
<h2 class="title">{{ T "linkRedirection.title" }}</h2>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
@param {String} [.Content] link label HTML
|
||||
@param {String} [.Title] title attribute
|
||||
@param {String} [.Class] custom CSS classes
|
||||
@param {String} [.Rel] rel attribute value
|
||||
@param {Boolean} [.Newtab] force external behavior
|
||||
@param {Boolean} [.Noreferrer] whether to include noreferrer (default: true)
|
||||
@param {Boolean} [.ExternalIcon] whether to show external-link icon
|
||||
@@ -14,6 +15,8 @@
|
||||
@param {Boolean} [.Card] whether to render card link layout
|
||||
@param {String} [.CardIcon] card icon URL or icon class
|
||||
@param {String} [.Download] download attribute value
|
||||
@param {Boolean} [.IsGuarded] explicitly enable or disable link guard
|
||||
@param {Object} [.Page] current page context
|
||||
*/ -}}
|
||||
|
||||
{{- /* Regular link rendering */ -}}
|
||||
@@ -32,6 +35,7 @@
|
||||
$externalIcon
|
||||
| and $isExternal
|
||||
| and (not (hasPrefix $ctx.Content `<img`))
|
||||
| and (not (hasPrefix $ctx.Content `<svg`))
|
||||
| and (not (strings.HasSuffix $ctx.Content `</i>`))
|
||||
| and (not (strings.HasSuffix $ctx.Content `):`))
|
||||
-}}
|
||||
@@ -101,7 +105,6 @@
|
||||
{{- $noreferrer = false -}}
|
||||
{{- end -}}
|
||||
{{- $url := urls.Parse .Destination -}}
|
||||
{{/* {{ partial "_debug/dump" $url }} */}}
|
||||
{{- if $url.IsAbs | and (not (in $blockSchemes $url.Scheme)) -}}
|
||||
{{- $isExternal = not (strings.HasPrefix .Destination site.BaseURL) -}}
|
||||
{{- end -}}
|
||||
@@ -118,12 +121,20 @@
|
||||
|
||||
{{- /* External link guard */ -}}
|
||||
{{- $isGuarded := false -}}
|
||||
{{- $guardConfig := $config.guard -}}
|
||||
{{- with .Page.Params.link_guard -}}
|
||||
{{- if reflect.IsMap . -}}
|
||||
{{- $guardConfig = (partial "function/snake2camel.html" .) | merge $guardConfig -}}
|
||||
{{- else -}}
|
||||
{{- $guardConfig = (dict "enable" .) | merge $guardConfig -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if
|
||||
$config.guard.enable
|
||||
$guardConfig.enable
|
||||
| and $isExternal
|
||||
| and (not (in $config.guard.allowDomains $url.Host))
|
||||
| and (not (in $guardConfig.allowDomains $url.Host))
|
||||
-}}
|
||||
{{- $isGuarded = true -}}
|
||||
{{- $isGuarded = .IsGuarded | default true -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $destination := cond $isGuarded (add (relLangURL "link") "?target=" (urlquery .Destination)) .Destination -}}
|
||||
@@ -143,7 +154,7 @@
|
||||
{{- with .Download -}}
|
||||
{{- $attrs = printf ` download="%s"` . | add $attrs -}}
|
||||
{{- end -}}
|
||||
{{- if $isGuarded | and (eq $config.guard.mode "modal") -}}
|
||||
{{- if $isGuarded | and (eq $guardConfig.mode "modal") -}}
|
||||
{{- $attrs = add $attrs ` data-guard="modal"` -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{{- with dict "Path" $destination | partial "function/resource.html" -}}
|
||||
{{- $destination = .RelPermalink -}}
|
||||
{{- end -}}
|
||||
{{- $options := dict "Destination" $destination -}}
|
||||
{{- $options := dict "Destination" $destination "Page" .Page -}}
|
||||
{{- if .IsNamedParams -}}
|
||||
{{- $options = dict "Content" (.Get "content") | merge $options -}}
|
||||
{{- $options = dict "Title" (.Get "title") | merge $options -}}
|
||||
@@ -12,11 +12,12 @@
|
||||
{{- $options = dict "Card" (.Get "card") | merge $options -}}
|
||||
{{- $options = dict "CardIcon" (.Get "card-icon") | merge $options -}}
|
||||
{{- $options = dict "Noreferrer" (.Get "noreferrer") | merge $options -}}
|
||||
{{- $options = dict "ExternalIcon" (.Get "external-icon") | merge $options -}}
|
||||
{{- $options = dict "IsGuarded" (.Get "isGuarded") | merge $options -}}
|
||||
{{- else -}}
|
||||
{{- $options = dict "Content" (.Get 1 | default (.Get 0)) | merge $options -}}
|
||||
{{- $options = dict "Title" (.Get 2) | merge $options -}}
|
||||
{{- $options = dict "Card" (.Get 3) | merge $options -}}
|
||||
{{- $options = dict "CardIcon" (.Get 4) | merge $options -}}
|
||||
{{- end -}}
|
||||
{{- $options = dict "ExternalIcon" (.Get "external-icon") | merge $options -}}
|
||||
{{- partial "plugin/link.html" $options -}}
|
||||
|
||||
+39
-12
@@ -1,3 +1,23 @@
|
||||
{{- /*
|
||||
[todo] refactor #206
|
||||
[todo] link_guard usage in data file
|
||||
Friends page template.
|
||||
|
||||
Usage:
|
||||
1. Friend link items are loaded from data/friends.yml.
|
||||
2. External link guard is disabled by default on this page.
|
||||
3. To enable guard for all friend links on the current page, set `link_guard` to `true` in front matter.
|
||||
|
||||
@example
|
||||
```md
|
||||
---
|
||||
title: friends
|
||||
layout: friends
|
||||
link_guard: true
|
||||
---
|
||||
```
|
||||
*/ -}}
|
||||
|
||||
{{- define "title" -}}
|
||||
{{- cond (.Param "capitalizeTitles") (title .Title) .Title -}}
|
||||
{{- if .Site.Params.withSiteTitle }} {{ .Site.Params.titleDelimiter }} {{ .Site.Title }}{{- end -}}
|
||||
@@ -5,6 +25,7 @@
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $isGuarded := .Params.link_guard | default false -}}
|
||||
<article class="page single special friends">
|
||||
<div class="header">
|
||||
{{- /* Title */ -}}
|
||||
@@ -16,18 +37,24 @@
|
||||
{{- /* Friend links */ -}}
|
||||
<script src="//at.alicdn.com/t/font_578712_g26jo2kbzd5qm2t9.js" async defer></script>
|
||||
<div class="friend-links">
|
||||
{{ range $index, $friend := hugo.Data.friends }}
|
||||
<a class="friend-link" title="{{ $friend.description | safeHTML }}" href="{{ $friend.url | safeURL }}" rel="external noopener" target="_blank">
|
||||
{{ if $friend.avatar }}
|
||||
{{- dict "Src" $friend.avatar "Alt" $friend.nickname "Title" $friend.description "Class" "friend-avatar" | partial "plugin/image.html" -}}
|
||||
{{ else }}
|
||||
<svg class="friend-avatar" aria-hidden="true">
|
||||
<use xlink:href="#icon-{{ add 1 $index }}"></use>
|
||||
</svg>
|
||||
{{ end }}
|
||||
<span class="friend-nickname" title="{{ $friend.nickname }}">@{{ $friend.nickname }}</span>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{- range $index, $friend := hugo.Data.friends -}}
|
||||
{{- $avatar := "" -}}
|
||||
{{- if $friend.avatar -}}
|
||||
{{- $avatar = dict "Src" $friend.avatar "Alt" $friend.nickname "Title" $friend.description "Class" "friend-avatar" | partial "plugin/image.html" -}}
|
||||
{{- else -}}
|
||||
{{- $avatar = printf `<svg class="friend-avatar" aria-hidden="true"><use xlink:href="#icon-%d"></use></svg>` (add 1 $index) -}}
|
||||
{{- end -}}
|
||||
{{- $nickname := printf `<span class="friend-nickname" title="%s">@%s</span>` $friend.nickname $friend.nickname -}}
|
||||
{{- $options := dict
|
||||
"Destination" $friend.url
|
||||
"Title" $friend.description
|
||||
"Content" (printf `%s%s` $avatar $nickname)
|
||||
"Class" "friend-link"
|
||||
"ExternalIcon" false
|
||||
"IsGuarded" $isGuarded
|
||||
-}}
|
||||
{{- partial "plugin/link.html" $options -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
{{- /* Content */ -}}
|
||||
|
||||
Reference in New Issue
Block a user