• English
  • Advanced Customization

    ModernDuang provides a rich set of configuration options, but if you need deeper customization, you can extend the theme through the following methods.

    Important: Always prefer using _config.modernduang.yml for configurable adjustments. Avoid editing theme source files directly — this way your customizations won't be lost when updating the theme.

    Overriding CSS Styles

    ModernDuang uses CSS custom properties (variables) to control colors, spacing, shadows, and other visual properties. You can override these variables in source/css/main.css to customize the appearance.

    Common CSS Variables

    Here are the most important CSS variables in the theme:

    :root {
      --primary: #6C9BCF;           /* Primary theme color */
      --primary-light: #A3C4E8;     /* Light theme color */
      --primary-dark: #4A7BB7;      /* Dark theme color */
      --bg-primary: #F5F0EB;        /* Main background color */
      --bg-secondary: #FFFFFF;      /* Secondary background (cards) */
      --text-primary: #2C3E50;      /* Main text color */
      --text-secondary: #7F8C8D;    /* Secondary text color */
      --border-color: #E8E0D5;      /* Border color */
      --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);   /* Small shadow */
      --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);  /* Medium shadow */
      --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);  /* Large shadow */
      --radius-sm: 8px;             /* Small border radius */
      --radius-md: 16px;            /* Medium border radius */
      --radius-lg: 24px;            /* Large border radius */
      --font-family: 'Inter', sans-serif;  /* Body font */
      --font-heading: 'Playfair Display', serif; /* Heading font */
      --font-mono: 'JetBrains Mono', monospace;  /* Monospace font */
    }

    Dark Mode Variables

    [data-theme="dark"] {
      --bg-primary: #1A1A2E;
      --bg-secondary: #16213E;
      --text-primary: #EAEAEA;
      --text-secondary: #A0A0A0;
      --border-color: #2A2A4A;
    }

    How to Override

    Edit source/css/main.css and add your custom styles at the end of the file:

    /* Custom theme color */
    :root {
      --primary: #E8A0BF;
      --primary-light: #F2C4D5;
      --primary-dark: #C97A9A;
    }
    
    /* Custom dark mode */
    [data-theme="dark"] {
      --primary: #F2C4D5;
      --primary-dark: #E8A0BF;
    }
    
    /* Adjust card shadow */
    .post-card {
      box-shadow: var(--shadow-lg);
      border-radius: var(--radius-lg);
    }

    Adding Custom JavaScript

    You can add custom JavaScript code in source/js/main.js for additional interactive functionality.

    // Custom JavaScript
    document.addEventListener('DOMContentLoaded', function() {
      // Your custom code
      console.log('Blog loaded!');
    
      // Example: add target="_blank" to all external links
      document.querySelectorAll('a[href^="http"]').forEach(link => {
        if (!link.href.includes(window.location.hostname)) {
          link.setAttribute('target', '_blank');
          link.setAttribute('rel', 'noopener noreferrer');
        }
      });
    });

    Modifying Layout Templates

    The theme's layout templates are located in the layout/ directory and use the EJS template engine. You can modify these files to adjust the HTML structure of your pages.

    Main Template Files

    FilePurpose
    layout/layout.ejsBase layout (HTML head, navigation, footer)
    layout/index.ejsHomepage template
    layout/post.ejsArticle page template
    layout/archive.ejsArchive page template
    layout/tags.ejsTags page template
    layout/categories.ejsCategories page template
    layout/links.ejsFriend links page template
    layout/partials/header.ejsNavigation header component
    layout/partials/footer.ejsFooter component
    layout/partials/comments.ejsComments component

    Example: Add Custom Meta Tags in the Head

    Edit layout/partials/header.ejs and add inside the <head> tag:

    <!-- Custom meta tags -->
    <meta name="theme-color" content="#6C9BCF">
    <meta name="msapplication-TileColor" content="#6C9BCF">

    Edit layout/partials/footer.ejs and add before </body>:

    <!-- Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'G-XXXXXXXXXX');
    </script>

    The "Exchange Links" section on the friend links page is powered by layout/_link-apply.md. This file uses standard Markdown syntax combined with special theme syntax to display your site information.

    Template Structure

    The section title is configured via YAML frontmatter at the top of the file. The body uses standard Markdown:

    ---
    title: Exchange Links
    ---
    
    Welcome to exchange links! Please read the following information before applying.
    
    ### My Site
    
    <!-- siteinfo -->
    
    ### Requirements
    
    1. Site content is healthy and positive
    2. Regularly updated, no significant dead links
    3. Already added my site to your links
    
    ### How to Apply
    
    Please leave a comment below with the following format:
    
    {%card%}
    Name: Your site name
    URL: https://yourblog.com
    Description: A short description (under 20 words)
    Avatar: https://yourblog.com/avatar.png
    Group: Friends
    {%card%}

    {%card%} Blocks

    {%card%}content{%card%} wraps content in a clay-styled card container, used to highlight your site information. Note that the opening and closing tags use the same syntax.

    <!-- siteinfo --> Placeholder

    <!-- siteinfo --> is a special placeholder that is automatically replaced with your site information table:

    PropertySource
    Site nameHexo _config.yml title field
    Site descriptionHexo _config.yml description field
    Site URLsiteInfo.url in _config.modernduang.yml
    AvatarsiteInfo.avatar in _config.modernduang.yml
    Atom feedsiteInfo.atom in _config.modernduang.yml

    Customizing the Apply Text

    You can freely edit layout/_link-apply.md with any standard Markdown syntax. Just keep the <!-- siteinfo --> placeholder to display your site information — the rest is fully customizable.


    Customizing the 404 Page

    ModernDuang includes a built-in 404 page. To customize it, copy and modify the theme's 404 template:

    cp themes/modernduang/layout/404.ejs layout/404.ejs

    Then edit layout/404.ejs and customize the content:

    <section class="error-section">
      <div class="error-content">
        <!-- Please write your code inside the error-content container -->
        <h1>404</h1>
        <p>Sorry, the page you are looking for does not exist.</p>
        <p>The link may be broken, or you may have entered the wrong address.</p>
        <a href="<%= url_for('/') %>">Back to Home</a>
      </div>
    </section>

    Adding Custom Fonts

    Method 1: Add Google Fonts via Config

    Configure the font option in _config.modernduang.yml:

    font:
      enable: true
      host: https://fonts.googleapis.com
      global:
        external: true
        families:
          - Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400
          - Inter:wght@300;400;500;600
          - JetBrains+Mono:wght@400;500
          - Noto+Sans+SC:wght@400;500;700   # Add Chinese font

    Tip for users in China: If Google Fonts loads slowly, change font.host to a mirror, such as https://fonts.googleapis.cn or https://fonts.loli.net.

    Method 2: Load Local Fonts via CSS

    Edit source/css/main.css and use @font-face to load local fonts:

    @font-face {
      font-family: 'CustomFont';
      src: url('/fonts/custom-font.woff2') format('woff2'),
           url('/fonts/custom-font.woff') format('woff');
      font-weight: 400;
      font-style: normal;
      font-display: swap;
    }
    
    body {
      font-family: 'CustomFont', var(--font-family);
    }

    Place font files in your Hexo site's source/fonts/ directory.


    Adding Custom Scripts

    Analytics Scripts

    For simple third-party scripts, use the footer.custom field with a single-line string:

    footer:
      custom: '<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>'

    For complex multi-line scripts (e.g., Google Analytics, Baidu Tongji), it's recommended to inject them via the EJS template instead — see the example in the Layout Templates section above.

    If you need to inject scripts in the <head> (rather than the footer), edit layout/partials/header.ejs and add your script tags inside the <head> element.


    Understanding Theme Scripts

    ModernDuang includes several Hexo helper scripts in the scripts/ directory that extend Hexo's build capabilities. You can create your own scripts in your Hexo site's scripts/ directory to add new functionality.

    Built-in Scripts

    ScriptPurpose
    scripts/mermaid.jsInjects Mermaid rendering scripts and styles for Mermaid code blocks in Markdown
    scripts/note-tags.jsRegisters custom blockquote tags ({% note %}, {% warning %}, {% declare %}, {% danger %})
    scripts/link-apply.jsProcesses {%card%} blocks and the <!-- siteinfo --> placeholder on the link apply page

    How mermaid.js Works

    This script detects the mermaid: true flag in page frontmatter during Hexo build. When detected, it injects the Mermaid CDN script and initialization code at the bottom of the page:

    // Simplified principle
    hexo.extend.filter.register('after_post_render', function(data) {
      if (data.mermaid) {
        // Inject mermaid.min.js CDN script
        // Add mermaid.initialize() initialization code
      }
      return data;
    });

    How note-tags.js Works

    This script registers a series of Hexo tag plugins for creating specially styled blockquotes in Markdown:

    {% note %}
    This is a note
    {% endnote %}
    
    {% warning %}
    This is a warning
    {% endwarning %}
    
    {% declare %}
    This is a declaration
    {% enddeclare %}
    
    {% danger %}
    This is a danger warning
    {% enddanger %}

    The script registers paired tags (note, warning, declare, danger) that wrap their content in styled HTML containers with icons, colors, and mouse-tracking glow effects.


    Summary

    What you want to doRecommended approach
    Change colors, fonts, layout optionsSet the corresponding option in _config.modernduang.yml
    Override CSS variablesEdit source/css/main.css
    Add analytics / tracking scriptsInject via layout/partials/footer.ejs
    Modify layout templatesOverride them in your site's layout/ directory
    Customize the link apply contentEdit layout/_link-apply.md
    Add Hexo helpers, filters, or tagsPlace .js files in your site's scripts/ directory