From 5be1e9acaad8fd84f01e5f7a969033d5c449430d Mon Sep 17 00:00:00 2001 From: Digital Studium Date: Sat, 22 Jul 2023 16:18:15 +0300 Subject: [PATCH] first commit --- LICENSE | 20 +++ README.md | 2 + i18n.csv | 6 + static/css/style.css | 180 ++++++++++++++++++++++++ static/images/github.svg | 1 + static/images/telegram.svg | 1 + static/images/youtube.svg | 1 + static/js/clipboard-polyfill.promise.js | 10 ++ static/js/copy.js | 58 ++++++++ templates/base.j2 | 22 +++ templates/components/all_languages.j2 | 19 +++ templates/components/author_and_date.j2 | 9 ++ templates/components/footer.j2 | 3 + templates/components/head.j2 | 18 +++ templates/components/header.j2 | 7 + templates/components/image.j2 | 11 ++ templates/components/index.j2 | 5 + templates/components/post_summary.j2 | 12 ++ templates/components/schema.j2 | 44 ++++++ templates/components/script.j2 | 3 + templates/components/section.j2 | 3 + templates/components/sidebar.j2 | 9 ++ templates/components/single.j2 | 7 + templates/components/social.j2 | 20 +++ templates/shortcodes.j2 | 5 + 25 files changed, 476 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 i18n.csv create mode 100644 static/css/style.css create mode 100644 static/images/github.svg create mode 100644 static/images/telegram.svg create mode 100644 static/images/youtube.svg create mode 100644 static/js/clipboard-polyfill.promise.js create mode 100644 static/js/copy.js create mode 100644 templates/base.j2 create mode 100644 templates/components/all_languages.j2 create mode 100644 templates/components/author_and_date.j2 create mode 100644 templates/components/footer.j2 create mode 100644 templates/components/head.j2 create mode 100644 templates/components/header.j2 create mode 100644 templates/components/image.j2 create mode 100644 templates/components/index.j2 create mode 100644 templates/components/post_summary.j2 create mode 100644 templates/components/schema.j2 create mode 100644 templates/components/script.j2 create mode 100644 templates/components/section.j2 create mode 100644 templates/components/sidebar.j2 create mode 100644 templates/components/single.j2 create mode 100644 templates/components/social.j2 create mode 100644 templates/shortcodes.j2 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..17993f6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2023 YOUR_NAME_HERE + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d5177ed --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# DigitalStudium theme +For Crater static site generator \ No newline at end of file diff --git a/i18n.csv b/i18n.csv new file mode 100644 index 0000000..3274acd --- /dev/null +++ b/i18n.csv @@ -0,0 +1,6 @@ +id|en|ru +by|by|автор +published|published|опубликовано +readmore|read more|читать дальше +next|next|вперёд +prev|previous|назад \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..992f61f --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,180 @@ +* { + word-wrap: break-word; + font-family: 'Open Sans', sans-serif; +} + +html { + background-color: #f2f2f2 +} + +article, +section { + font-size: 1.3rem !important; + padding: 1.5rem; + margin-bottom: 1rem; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, .2), 0 6px 20px 0 rgba(0, 0, 0, .19); + background-color: white; + overflow: auto +} + +pre { + margin: 0 !important; + border-radius: 0 !important; + padding: .7rem !important; + font-weight: 500; + overflow: auto +} + +blockquote { + font-family: Lato; + font-size: 1.2rem; + line-height: 1.5; + color: #555; + text-align: left; + border-left: 4px solid #ccc; + padding: 1rem; + margin: 1rem 0; + background-color: #f8f8f8; +} + +.copy-code-button { + cursor: pointer; + display: block; + margin: 1rem 0 -2px auto; + font-size: 1.1rem !important +} + +button { + padding: 0.5rem; + border: 0.1; +} + +/* images settings */ + +/* img { + max-width: 100%; + height: auto +} */ + +.post-image, +.home-image { + float: left; + padding-right: 1rem; +} + +.post-image { + width: 50%; +} + +.home-image { + width: 30%; +} + + + +/* Блок для правильной вёрстки аудио/видео начало */ +/* Применяем max-width для замещаемых элементов и контролов формы. */ +img, +video, +audio, +canvas, +input, +select, +button, +progress { + max-width: 100%; +} + +/* Заставляем поля с типом file и submit переносить текст */ +input[type="file"], +input[type="submit"] { + white-space: pre-wrap; +} + +/* Чиним прогрессбар и поле-ползунок */ +progress, +input[type="range"] { + width: 100%; +} + +/* Фиксим поля с типом Number в Firefox */ +@supports (--moz-appearance: none) { + input[type="number"] { + width: 100%; + } +} + +/* Блок для аудио/видео конец */ + + + +@media screen and (max-width:50em) { + .home-image { + width: 50%; + } + + .sidebar { + display: none + } +} + +/* gird settings */ + +body { + display: grid; + grid-gap: 1rem; + grid-template-columns: repeat(6, 1fr); +} + +header, +footer, +main { + grid-column-start: 2; +} + +.social-icons { + grid-column-start: 3; + grid-column-end: 5; + justify-self: end; +} + +footer, +main { + grid-column-end: 5 +} + +.sidebar { + grid-column-start: 5; + grid-column-end: 6 +} + +main, +.sidebar { + grid-row-start: 2 +} + +@media screen and (max-width:100em) { + + header, + footer, + main { + grid-column-start: 1 + } + + footer, + .sidebar { + grid-column-end: 7 + } + + header { + grid-column-end: 3 + } +} + +@media screen and (max-width:50em) { + + header, + main { + grid-column-end: 7 + } +} \ No newline at end of file diff --git a/static/images/github.svg b/static/images/github.svg new file mode 100644 index 0000000..d393c16 --- /dev/null +++ b/static/images/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/telegram.svg b/static/images/telegram.svg new file mode 100644 index 0000000..e2fa2f7 --- /dev/null +++ b/static/images/telegram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/youtube.svg b/static/images/youtube.svg new file mode 100644 index 0000000..d3fd48e --- /dev/null +++ b/static/images/youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/js/clipboard-polyfill.promise.js b/static/js/clipboard-polyfill.promise.js new file mode 100644 index 0000000..e59d67e --- /dev/null +++ b/static/js/clipboard-polyfill.promise.js @@ -0,0 +1,10 @@ +!function(root,factory){"object"==typeof exports&&"object"==typeof module?module.exports=factory():"function"==typeof define&&define.amd?define([],factory):"object"==typeof exports?exports.clipboard=factory():root.clipboard=factory()}("undefined"!=typeof self?self:this,function(){return function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{enumerable:!0,get:getter})},__webpack_require__.r=function(exports){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.t=function(value,mode){if(1&mode&&(value=__webpack_require__(value)),8&mode)return value;if(4&mode&&"object"==typeof value&&value&&value.__esModule)return value;var ns=Object.create(null);if(__webpack_require__.r(ns),Object.defineProperty(ns,"default",{enumerable:!0,value:value}),2&mode&&"string"!=typeof value)for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=2)}([function(module,exports,__webpack_require__){"use strict";var __awaiter=this&&this.__awaiter||function(thisArg,_arguments,P,generator){return new(P||(P=Promise))(function(resolve,reject){function fulfilled(value){try{step(generator.next(value))}catch(e){reject(e)}}function rejected(value){try{step(generator.throw(value))}catch(e){reject(e)}}function step(result){result.done?resolve(result.value):new P(function(resolve){resolve(result.value)}).then(fulfilled,rejected)}step((generator=generator.apply(thisArg,_arguments||[])).next())})},__generator=this&&this.__generator||function(thisArg,body){var f,y,t,g,_={label:0,sent:function(){if(1&t[0])throw t[1];return t[1]},trys:[],ops:[]};return g={next:verb(0),throw:verb(1),return:verb(2)},"function"==typeof Symbol&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return function(op){if(f)throw new TypeError("Generator is already executing.");for(;_;)try{if(f=1,y&&(t=2&op[0]?y.return:op[0]?y.throw||((t=y.return)&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;switch(y=0,t&&(op=[2&op[0],t.value]),op[0]){case 0:case 1:t=op;break;case 4:return _.label++,{value:op[1],done:!1};case 5:_.label++,y=op[1],op=[0];continue;case 7:op=_.ops.pop(),_.trys.pop();continue;default:if(!(t=(t=_.trys).length>0&&t[t.length-1])&&(6===op[0]||2===op[0])){_=0;continue}if(3===op[0]&&(!t||op[1]>t[0]&&op[1]-1)return debugLog('UA "Edge" => assuming success'),[2];if(copyUsingTempSelection(document.body,data))return debugLog("copyUsingTempSelection worked"),[2];if(function(data){var tempElem=document.createElement("div");tempElem.setAttribute("style","-webkit-user-select: text !important"),tempElem.textContent="temporary element",document.body.appendChild(tempElem);var success=copyUsingTempSelection(tempElem,data);return document.body.removeChild(tempElem),success}(data))return debugLog("copyUsingTempElem worked"),[2];if(void 0!==(text=data.getData(TEXT_PLAIN))&&function(str){debugLog("copyTextUsingDOM");var tempElem=document.createElement("div");tempElem.setAttribute("style","-webkit-user-select: text !important");var spanParent=tempElem;tempElem.attachShadow&&(debugLog("Using shadow DOM."),spanParent=tempElem.attachShadow({mode:"open"}));var span=document.createElement("span");span.innerText=str,spanParent.appendChild(span),document.body.appendChild(tempElem),selectionSet(span);var result=document.execCommand("copy");return selectionClear(),document.body.removeChild(tempElem),result}(text))return debugLog("copyTextUsingDOM worked"),[2];throw"Copy command failed."})})}function writeText(s){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(_a){return navigator.clipboard&&navigator.clipboard.writeText?(debugLog("Using `navigator.clipboard.writeText()`."),[2,navigator.clipboard.writeText(s)]):[2,write(DTFromText(s))]})})}function read(){return __awaiter(this,void 0,void 0,function(){var _a;return __generator(this,function(_b){switch(_b.label){case 0:return _a=DTFromText,[4,readText()];case 1:return[2,_a.apply(void 0,[_b.sent()])]}})})}function readText(){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(_a){if(navigator.clipboard&&navigator.clipboard.readText)return debugLog("Using `navigator.clipboard.readText()`."),[2,navigator.clipboard.readText()];if(seemToBeInIE())return debugLog("Reading text using IE strategy."),[2,function(){return __awaiter(this,void 0,void 0,function(){var text;return __generator(this,function(_a){if(""===(text=window.clipboardData.getData("Text")))throw"Empty clipboard or could not read plain text from clipboard";return[2,text]})})}()];throw"Read is not supported in your browser."})})}exports.setDebugLog=setDebugLog,exports.suppressWarnings=suppressWarnings,exports.write=write,exports.writeText=writeText,exports.read=read,exports.readText=readText;var useStarShown=!1;function useStar(){useStarShown||(showWarnings&&warn('You are using the deprecated default object of `clipboard-polyfill`. Please switch to `import * as clipboard from "clipboard-polyfill"` and see https://github.com/lgarron/clipboard-polyfill/issues/101 for more info.'),useStarShown=!0)}var ClipboardPolyfillDefault=function(){function ClipboardPolyfillDefault(){}return ClipboardPolyfillDefault.setDebugLog=function(f){return useStar(),setDebugLog(f)},ClipboardPolyfillDefault.suppressWarnings=function(){return useStar(),suppressWarnings()},ClipboardPolyfillDefault.write=function(data){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(_a){return useStar(),[2,write(data)]})})},ClipboardPolyfillDefault.writeText=function(s){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(_a){return useStar(),[2,writeText(s)]})})},ClipboardPolyfillDefault.read=function(){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(_a){return useStar(),[2,read()]})})},ClipboardPolyfillDefault.readText=function(){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(_a){return useStar(),[2,readText()]})})},ClipboardPolyfillDefault.DT=DT_1.DT,ClipboardPolyfillDefault}();exports.default=ClipboardPolyfillDefault;var FallbackTracker=function(){return function(){this.success=!1}}();function execCopy(data){var tracker=new FallbackTracker,listener=function(tracker,data,e){debugLog("listener called"),tracker.success=!0,data.forEach(function(value,key){e.clipboardData.setData(key,value),key===TEXT_PLAIN&&e.clipboardData.getData(key)!=value&&(debugLog("setting text/plain failed"),tracker.success=!1)}),e.preventDefault()}.bind(this,tracker,data);document.addEventListener("copy",listener);try{document.execCommand("copy")}finally{document.removeEventListener("copy",listener)}return tracker.success}function copyUsingTempSelection(e,data){selectionSet(e);var success=execCopy(data);return selectionClear(),success}function selectionSet(elem){var sel=document.getSelection();if(sel){var range=document.createRange();range.selectNodeContents(elem),sel.removeAllRanges(),sel.addRange(range)}}function selectionClear(){var sel=document.getSelection();sel&&sel.removeAllRanges()}function DTFromText(s){var dt=new DT_1.DT;return dt.setData(TEXT_PLAIN,s),dt}function seemToBeInIE(){return"undefined"==typeof ClipboardEvent&&void 0!==window.clipboardData&&void 0!==window.clipboardData.setData}},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var dataTypes=["text/plain","text/html"],warn=function(){(console.warn||console.log).call(arguments)}.bind(console,"[clipboard-polyfill]"),showWarnings=!0;exports.suppressDTWarnings=function(){showWarnings=!1};var DT=function(){function DT(){this.m={}}return DT.prototype.setData=function(type,value){showWarnings&&-1===dataTypes.indexOf(type)&&warn("Unknown data type: "+type,"Call clipboard.suppressWarnings() to suppress this warning."),this.m[type]=value},DT.prototype.getData=function(type){return this.m[type]},DT.prototype.forEach=function(f){for(var k in this.m)f(this.m[k],k)},DT}();exports.DT=DT},function(module,exports,__webpack_require__){module.exports=__webpack_require__(3)},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),__webpack_require__(4),function(m){for(var p in m)exports.hasOwnProperty(p)||(exports[p]=m[p])}(__webpack_require__(0))},function(module,exports,__webpack_require__){(function(process,global){ +/*! + * @overview es6-promise - a tiny implementation of Promises/A+. + * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) + * @license Licensed under MIT license + * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE + * @version v4.2.5+7f2b526d + */ +!function(global,factory){module.exports=factory()}(0,function(){"use strict";function isFunction(x){return"function"==typeof x}var isArray=Array.isArray?Array.isArray:function(x){return"[object Array]"===Object.prototype.toString.call(x)},len=0,vertxNext=void 0,customSchedulerFn=void 0,asap=function(callback,arg){queue[len]=callback,queue[len+1]=arg,2===(len+=2)&&(customSchedulerFn?customSchedulerFn(flush):scheduleFlush())};var browserWindow="undefined"!=typeof window?window:void 0,browserGlobal=browserWindow||{},BrowserMutationObserver=browserGlobal.MutationObserver||browserGlobal.WebKitMutationObserver,isNode="undefined"==typeof self&&void 0!==process&&"[object process]"==={}.toString.call(process),isWorker="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function useSetTimeout(){var globalSetTimeout=setTimeout;return function(){return globalSetTimeout(flush,1)}}var queue=new Array(1e3);function flush(){for(var i=0;i1)for(var i=1;i + +{% include "components/head.j2" %} + + + {% include "components/header.j2" %} +
+ {% if home %} + {% include "components/index.j2" %} + {% elif section %} + {% include "components/section.j2" %} + {% else %} + {% include "components/single.j2" %} + {% endif %} +
+ {% include "components/sidebar.j2" %} + {% include "components/footer.j2" %} + {% include "components/script.j2" %} + {% include "components/schema.j2" %} + + + \ No newline at end of file diff --git a/templates/components/all_languages.j2 b/templates/components/all_languages.j2 new file mode 100644 index 0000000..c5beae3 --- /dev/null +++ b/templates/components/all_languages.j2 @@ -0,0 +1,19 @@ +{% if home %} +

🌐 + {% for key, value in config.languages.items() %} + {% if key != language %} + {{ value.language_name }} + {% endif %} + {% endfor %} +

+{% else %} +

+ 🌐 + {% for key, value in config.languages.items() %} + {% if key != language %} + {{ + value.language_name }} + {% endif %} + {% endfor %} +

+{% endif %} \ No newline at end of file diff --git a/templates/components/author_and_date.j2 b/templates/components/author_and_date.j2 new file mode 100644 index 0000000..0e6399b --- /dev/null +++ b/templates/components/author_and_date.j2 @@ -0,0 +1,9 @@ + + + +
+ 🧘 {{ translate('by', language) | capitalize }}: + {{ config['languages'][language]['author'] }} +
\ No newline at end of file diff --git a/templates/components/footer.j2 b/templates/components/footer.j2 new file mode 100644 index 0000000..f2de25d --- /dev/null +++ b/templates/components/footer.j2 @@ -0,0 +1,3 @@ +
+ {{ translate('copyright_message', language) }} +
diff --git a/templates/components/head.j2 b/templates/components/head.j2 new file mode 100644 index 0000000..5a2b43c --- /dev/null +++ b/templates/components/head.j2 @@ -0,0 +1,18 @@ + + + + {% set title = config.languages[language].title %} + {% set description = config.languages[language].description %} + {% if section %} + {% set title = (translate(section, language) | capitalize) + " | " + title %} + {% set description = title %} + {% elif not home %} + {% set title = post.title + " | " + title %} + {% set description = post.description %} + {% endif %} + {{ title }} + + + + {% if config.custom_css %}{% endif %} + diff --git a/templates/components/header.j2 b/templates/components/header.j2 new file mode 100644 index 0000000..03316ce --- /dev/null +++ b/templates/components/header.j2 @@ -0,0 +1,7 @@ +
+ + {{ config['languages'][language]['title'] }} +

{{ config['languages'][language]['description'] }}

+
+ {% include "components/all_languages.j2" %} +
\ No newline at end of file diff --git a/templates/components/image.j2 b/templates/components/image.j2 new file mode 100644 index 0000000..368c228 --- /dev/null +++ b/templates/components/image.j2 @@ -0,0 +1,11 @@ +{% if post.image %} +

+ {% if home or section %} + + {{ image_title }} + + {% else %} + {{ image_title }} + {% endif %} +

+{% endif %} \ No newline at end of file diff --git a/templates/components/index.j2 b/templates/components/index.j2 new file mode 100644 index 0000000..e2fca1c --- /dev/null +++ b/templates/components/index.j2 @@ -0,0 +1,5 @@ +{% for section, urls in posts[language].items() %} +{% for url, post in urls.items() %} +{% include "components/post_summary.j2" %} +{% endfor %} +{% endfor %} \ No newline at end of file diff --git a/templates/components/post_summary.j2 b/templates/components/post_summary.j2 new file mode 100644 index 0000000..acf873d --- /dev/null +++ b/templates/components/post_summary.j2 @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/templates/components/schema.j2 b/templates/components/schema.j2 new file mode 100644 index 0000000..20b7782 --- /dev/null +++ b/templates/components/schema.j2 @@ -0,0 +1,44 @@ +{% if home %} + +{% else %} + +{% endif %} \ No newline at end of file diff --git a/templates/components/script.j2 b/templates/components/script.j2 new file mode 100644 index 0000000..2d4d120 --- /dev/null +++ b/templates/components/script.j2 @@ -0,0 +1,3 @@ +{% for include in includes %} + +{% endfor %} \ No newline at end of file diff --git a/templates/components/section.j2 b/templates/components/section.j2 new file mode 100644 index 0000000..1dd8a77 --- /dev/null +++ b/templates/components/section.j2 @@ -0,0 +1,3 @@ +{% for url, post in posts[language][section].items() %} +{% include "components/post_summary.j2" %} +{% endfor %} \ No newline at end of file diff --git a/templates/components/sidebar.j2 b/templates/components/sidebar.j2 new file mode 100644 index 0000000..456e926 --- /dev/null +++ b/templates/components/sidebar.j2 @@ -0,0 +1,9 @@ + diff --git a/templates/components/single.j2 b/templates/components/single.j2 new file mode 100644 index 0000000..4bae3ad --- /dev/null +++ b/templates/components/single.j2 @@ -0,0 +1,7 @@ +
+

{{ post.title }}

+ {% include "components/author_and_date.j2" %} + {% include "components/image.j2" %} + {{ post.content }} +
+ diff --git a/templates/components/social.j2 b/templates/components/social.j2 new file mode 100644 index 0000000..6384b35 --- /dev/null +++ b/templates/components/social.j2 @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/templates/shortcodes.j2 b/templates/shortcodes.j2 new file mode 100644 index 0000000..c024064 --- /dev/null +++ b/templates/shortcodes.j2 @@ -0,0 +1,5 @@ +{% macro audio(src) %} + +{% endmacro %} \ No newline at end of file