侧边栏添加日历组件 在 source/_data 路径下新建一个 widget.yml 文件
以后所有自定义的侧边栏组件都可以写在这里面,具体写法参考 butterfly 官方文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 top:   -  class_name:  card-times      id_name:  card-widget-calendar      name:      icon:      html:        <div  id="calendar-area-left">          <div  id="calendar-week"></div>          <div  id="calendar-date"></div>          <div  id="calendar-solar"></div>          <div  id="calendar-lunar"></div>        </div>        <div  id="calendar-area-right">          <div  id="calendar-main">            <div  class="calendar-rh">              <div  class="calendar-d0"><a>日</a></div>              <div  class="calendar-d1"><a>一</a></div>              <div  class="calendar-d2"><a>二</a></div>              <div  class="calendar-d3"><a>三</a></div>              <div  class="calendar-d4"><a>四</a></div>              <div  class="calendar-d5"><a>五</a></div>              <div  class="calendar-d6"><a>六</a></div>            </div>          </div>        </div>    -  class_name:  card-times      id_name:  card-widget-schedule      name:      icon:      html:        <div  id="schedule-area-left">          <div  id="schedule-title">距离决赛</div>          <div  id="schedule-days">000</div>          <div  id="schedule-date">2024-12-20</div>        </div>        <div  id="schedule-area-right">          <div  class="schedule-r0">            <div  class="schedule-d0">本年</div>            <div  class="schedule-d1">              <span  id="p_span_year"  class="aside-span1"></span>              <span  class="aside-span2"></span>              <progress  max="365"  value="54"  id="pBar_year"></progress>            </div>          </div>          <div  class="schedule-r1">            <div  class="schedule-d0">本月</div>            <div  class="schedule-d1">              <span  id="p_span_month"  class="aside-span1"></span>              <span  class="aside-span2"></span>              <progress  max="30"  value="17"  id="pBar_month"></progress>            </div>          </div>          <div  class="schedule-r2">            <div  class="schedule-d0">本周</div>            <div  class="schedule-d1">              <span  id="p_span_week"  class="aside-span1"></span>              <span  class="aside-span2"></span>              <progress  max="7"  value="1"  id="pBar_week"></progress>            </div>          </div>        </div>  
 
引入 lunar.js 从链接地址 下载 lunar.js 文件放在 source/js 路径下
calendar.js 路径 source/js 下新建 calendar.js 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 document .addEventListener ("DOMContentLoaded" , () =>  {    cardTimes ();     cardRefreshTimes (); });  document .addEventListener ("pjax:complete" , () =>  {    cardTimes ();     cardRefreshTimes (); })  var  now = new  Date ();var  year, month, week, date, dates, weekStr, monthStr;var  asideTime, asideDay, asideDayNum;var  animalYear, ganzhiYear, lunarMon, lunarDay;function  cardRefreshTimes ( ) {    var  cardWidgetSchedule = document .getElementById ("card-widget-schedule" );     if  (cardWidgetSchedule) {         asideDay = (now - asideTime) / 1e3  / 60  / 60  / 24 ;         cardWidgetSchedule.querySelector ("#pBar_year" ).value  = asideDay;         cardWidgetSchedule.querySelector ("#p_span_year" ).innerHTML  = (asideDay / 365  * 100 ).toFixed (2 ) + "%" ;         cardWidgetSchedule.querySelector (".schedule-r0 .schedule-d1 .aside-span2" ).innerHTML  = "还剩<a> "  + (365  - asideDay).toFixed (0 ) + " </a>天" ;         cardWidgetSchedule.querySelector ("#pBar_month" ).value  = date;         cardWidgetSchedule.querySelector ("#pBar_month" ).max  = dates;         cardWidgetSchedule.querySelector ("#p_span_month" ).innerHTML  = (date / dates * 100 ).toFixed (2 ) + "%" ;         cardWidgetSchedule.querySelector (".schedule-r1 .schedule-d1 .aside-span2" ).innerHTML  = "还剩<a> "  + (dates - date) + " </a>天" ;         cardWidgetSchedule.querySelector ("#pBar_week" ).value  = week == 0  ? 7  : week;         cardWidgetSchedule.querySelector ("#p_span_week" ).innerHTML  = ((week == 0  ? 7  : week) / 7  * 100 ).toFixed (2 ) + "%" ;         cardWidgetSchedule.querySelector (".schedule-r2 .schedule-d1 .aside-span2" ).innerHTML  = "还剩<a> "  + (7  - (week == 0  ? 7  : week)) + " </a>天" ;     } } function  cardTimes ( ) {    year = now.getFullYear ();     month = now.getMonth ();     week = now.getDay ();     date = now.getDate ();     var  cardWidgetCalendar = document .getElementById ("card-widget-calendar" );     if  (cardWidgetCalendar) {         var  year_flag = year % 4  == 0  && year % 100  != 0  || year % 400  == 0  ? true  : false ;         switch  (week) {             case  0 : weekStr = "周日" ; break ;             case  1 : weekStr = "周一" ; break ;             case  2 : weekStr = "周二" ; break ;             case  3 : weekStr = "周三" ; break ;             case  4 : weekStr = "周四" ; break ;             case  5 : weekStr = "周五" ; break ;             case  6 : weekStr = "周六" ; break ;             default : console .log ("异常情况" );         }         switch  (month) {             case  0 : monthStr = "1月" ; dates = 31 ; break ;             case  1 : monthStr = "2月" ; dates = year_flag ? 29  : 28 ; break ;             case  2 : monthStr = "3月" ; dates = 31 ; break ;             case  3 : monthStr = "4月" ; dates = 30 ; break ;             case  4 : monthStr = "5月" ; dates = 31 ; break ;             case  5 : monthStr = "6月" ; dates = 30 ; break ;             case  6 : monthStr = "7月" ; dates = 31 ; break ;             case  7 : monthStr = "8月" ; dates = 31 ; break ;             case  8 : monthStr = "9月" ; dates = 30 ; break ;             case  9 : monthStr = "10月" ; dates = 31 ; break ;             case  10 : monthStr = "11月" ; dates = 30 ; break ;             case  11 : monthStr = "12月" ; dates = 31 ; break ;             default : console .log ("异常情况" );         }         var  week_first = (week + 8  - date % 7 ) % 7 ;         var  count_days = "" ;         var  count_flag = false ;         var  ds;         var  row_h = 7  - week_first;          var  row_f = (dates - row_h) % 7 ;          var  rows = row_f == 0  ? Math .floor ((dates - row_h) / 7 ) + 1  : Math .floor ((dates - row_h) / 7 ) + 2 ;         var  calendar = cardWidgetCalendar.querySelector ("#calendar-main" );         var  gap = cardWidgetCalendar.querySelector ("#calendar-date" );         switch  (rows) {             case  4 : gap.style .fontSize  = "36px" ; break ;             case  5 : gap.style .fontSize  = "48px" ; break ;             case  6 : gap.style .fontSize  = "64px" ; break ;             default : gap.style .fontSize  = "64px" ;         }         for  (let  r = 0 ; r < rows; r++) {             if  (calendar.querySelector (".calendar-r"  + r) == null ) {                 calendar.innerHTML  += "<div class='calendar-r"  + r + "'></div>" ;             }             for  (let  d = 0 ; d < 7 ; d++) {                 if  (r == 0  && d == week_first) {                      count_days = 1 ;                     count_flag = true ;                 }                 if  (count_days == date) {                      ds = " class='now'" ;                 } else  ds = "" ;                 if  (calendar.querySelector (".calendar-r"  + r + " .calendar-d"  + d + " a" ) == null ) {                     calendar.querySelector (".calendar-r"  + r).innerHTML  += "<div class='calendar-d"  + d + "'><a"  + ds + ">"  + count_days + "</a></div>" ;                 }                 if  (count_days >= dates) {                     count_days = "" ;                     count_flag = false ;                 }                 if  (count_flag) count_days += 1 ;             }         }         var  lunar = chineseLunar.solarToLunar (new  Date (year, month, date));         animalYear = chineseLunar.format (lunar, "A" );          ganzhiYear = chineseLunar.format (lunar, "T" ).slice (0 , -1 );          lunarMon = chineseLunar.format (lunar, "M" );          lunarDay = chineseLunar.format (lunar, "d" );          var  anniversary = new  Date ("2024/12/20 08:30:00" );         var  countDown = Math .floor ((anniversary - now) / 1e3  / 60  / 60  / 24 );         asideTime = new  Date (new  Date ().getFullYear () + "/01/01 00:00:00" );	         asideDay = (now - asideTime) / 1e3  / 60  / 60  / 24 ;         asideDayNum = Math .floor (asideDay);         var  asideWeekNum = ((week - asideDayNum % 7 ) >= 0 ) ? (Math .ceil (asideDayNum / 7 )) : (Math .ceil (asideDayNum / 7 ) + 1 );         cardWidgetCalendar.querySelector ("#calendar-week" ).innerHTML  = "第"  + asideWeekNum + "周 "  + weekStr;          cardWidgetCalendar.querySelector ("#calendar-date" ).innerHTML  = date.toString ().padStart (2 , '0' );          cardWidgetCalendar.querySelector ("#calendar-solar" ).innerHTML  = year + "年"  + monthStr + " 第"  + asideDay.toFixed (0 ) + "天" ;          cardWidgetCalendar.querySelector ("#calendar-lunar" ).innerHTML  = ganzhiYear + animalYear + "年 "  + lunarMon + lunarDay;          document .getElementById ("schedule-days" ).innerHTML  = countDown;      } } 
 
calendar.css 路径 source/css 下新建 calendar.css 文件
css 代码不一定全(比如部分公共样式),遗漏的可以自行 F12 调试补充