快轉到主要內容
  1. 全部文章/

Hugo 可折疊 iframe Shortcode

·1136 字·3 分鐘
目錄
Hugo Shortcode - 本文屬於一個選集。
§ 1: 本文

前言
#

Hugo 動畫背景|3D網格加代碼瀑布風格 這邊文章中,我想要直接在文內展示該動畫背景。我可以直接在 Markdown 檔案中編寫 HTML iframe 元素創建,但我想要限制其高度,若超過便折疊,透過按鈕選擇是否展開,這樣的話更美觀且易於閱讀,就像Hugo Blowfish 主題 程式碼區塊樣式與折疊 這篇文章中提到的「可折疊程式碼區塊」,於是我透過 Perplexity 協助編寫了這個「可折疊 iframe Shortcode」。

展示
#

展示檔案路徑
#

創建/static/demo路徑,將你要展示的 .html 檔存放在該路徑下。

新增 CSS 設定
#

編輯/assets/css路徑下的custom.css,添加:

/* /layouts/shortcodes/iframe.html */
/* iframe 容器 */
.iframe-container {
  position: relative;
  margin: 1.5rem 0;
}

/* 折疊狀態 */
.iframe-container.collapsible {
  max-height: 400px;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

/* 展開狀態 */
.iframe-container.expanded {
  max-height: none;
}

/* 漸層遮罩 */
.iframe-container.collapsible::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 80px;
  background: linear-gradient(to bottom, transparent, var(--color-background));
  pointer-events: none;
}

.iframe-container.expanded::after {
  display: none;
}

/* 展開按鈕 */
.iframe-expand-btn {
  display: block;
  width: 100%;
  padding: 0.5rem;
  margin-top: 0.5rem;
  background: var(--color-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-base);
  cursor: pointer;
  font-size: 0.875rem;
  text-align: center;
  transition: background 0.2s;
}

.iframe-expand-btn:hover {
  background: var(--color-secondary-hover);
}

如果主題不是使用 Blowfish,上述設定的參數可能要重新檢查。

創建 iframe Shortcode 並導入 JavaScript
#

/layouts/shortcodes下創建iframe.html,並編輯:

<div class="iframe-container">
  <iframe src="{{ .Get "src" }}" 
          width="{{ .Get "width" | default "100%" }}" 
          height="{{ .Get "height" | default "600px" }}" 
          loading="lazy">
  </iframe>
</div>
{{ if not (.Page.Scratch.Get "iframe-js-loaded") }}
  {{ .Page.Scratch.Set "iframe-js-loaded" true }}
  <script src="/js/collapsible-iframe.js" defer></script>
{{ end }}

創建 JavaScript
#

編輯/static/js/collapsible-iframe.js,如路徑不存在就手動建立。

// static/js/collapsible-iframe.js
(function() {
  const containers = document.querySelectorAll('.iframe-container');
  
  // 從 HTML 讀取翻譯文字,預設為英文,這段是為了供多語言網站顯示對應文字,可直接將`Expand Content ▼`改為`展開完整內容 ▼`;`Collapse Content ▲`改為`折疊內容 ▲`
  const iframeExpandText = document.documentElement.dataset.iframeExpandText || 'Expand Content ▼';
  const iframeCollapseText = document.documentElement.dataset.iframeCollapseText || 'Collapse Content ▲';
  
  containers.forEach(function(container) {
    // 避免重複處理
    if (container.dataset.processed) return;
    container.dataset.processed = 'true';
    
    const iframe = container.querySelector('iframe');
    const iframeHeight = parseInt(iframe.getAttribute('height')) || 600;
    
    // 只對高度超過 400px 的 iframe 啟用折疊功能
    if (iframeHeight > 400) {
      // 設定容器為折疊狀態
      container.classList.add('collapsible');
      
      // 建立展開/折疊按鈕
      const btn = document.createElement('button');
      btn.className = 'iframe-expand-btn';
      btn.innerHTML = '<span class="expand-text">' + iframeExpandText + '</span><span class="collapse-text" style="display:none;">' + iframeCollapseText + '</span>';
      
      // 將按鈕插入到容器後面
      container.parentNode.insertBefore(btn, container.nextSibling);
      
      // 按鈕點擊事件
      btn.addEventListener('click', function() {
        const expandSpan = btn.querySelector('.expand-text');
        const collapseSpan = btn.querySelector('.collapse-text');
        
        if (container.classList.contains('collapsible')) {
          // 展開
          container.classList.remove('collapsible');
          container.classList.add('expanded');
          expandSpan.style.display = 'none';
          collapseSpan.style.display = 'inline';
        } else {
          // 折疊
          container.classList.remove('expanded');
          container.classList.add('collapsible');
          expandSpan.style.display = 'inline';
          collapseSpan.style.display = 'none';
          container.scrollIntoView({ behavior: 'smooth', block: 'start' });
        }
      });
    }
  });
})();

大功告成,如果你是多語言網站,請繼續參考下面步驟。

折疊按鈕多語言設定
#

修改 Shortcode
#

修改iframe.html,將:

{{ if not (.Page.Scratch.Get "iframe-js-loaded") }}
  {{ .Page.Scratch.Set "iframe-js-loaded" true }}
  <script src="/js/collapsible-iframe.js" defer></script>
{{ end }}

改為:

{{ if not (.Page.Scratch.Get "iframe-js-loaded") }}
  {{ .Page.Scratch.Set "iframe-js-loaded" true }}
  <script>
    document.documentElement.dataset.iframeExpandText = "{{ i18n "shortcode.collapsible-iframe.expand" }}";
    document.documentElement.dataset.iframeCollapseText = "{{ i18n "shortcode.collapsible-iframe.collapse" }}";
  </script>
  <script src="/js/collapsible-iframe.js" defer></script>
{{ end }}

編輯 i18n 設定檔
#

編輯 /i18n 路徑下的設定檔,以繁體中文zh-TW.yaml為例,在檔案中新增:

shortcode:
  collapsible-iframe:
    expand: "展開完整內容 ▼"
    collapse: "折疊內容 ▲"

Done!

使用方法
#

接著你就可以在 Markdown 檔案中使用:

{{< iframe src="/demo/檔名.html" width="自訂" height="自訂" >}}

不添加widthheigh的話,預設為100%600px,可到iframe.html中修改。

透過郵件回覆
YoZ 柚子
作者
YoZ 柚子
韓國實用音樂系留學生/FOSS Nerd/ISTJ/襯衫、墨鏡愛好者
Hugo Shortcode - 本文屬於一個選集。
§ 1: 本文

相關文章