diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index 7128cac..942ad07 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,12 @@ Gokarna is an opinionated theme with a focus on minimalism and simplicity. - Customizable header - Responsive - Available in light and dark themes -- Native fonts and support for [feather icons](https://feathericons.com/) +- Native fonts and support for [feather icons](https://feathericons.com/) and [svg icons](http://localhost:1313/posts/theme-documentation-advanced/#icons-on-homepage) - Syntax highlighting - SEO Ready - Option to add custom javascript and css - RSS Feed +- Math typesetting using [Katex](https://gokarna-hugo.netlify.app/posts/theme-documentation-advanced/#katex) ## Screenshots diff --git a/exampleSite/config.toml b/exampleSite/config.toml index 57d585a..63daa60 100644 --- a/exampleSite/config.toml +++ b/exampleSite/config.toml @@ -21,7 +21,14 @@ pygmentsStyle = "monokai" """ - showPostsOnHomePage = "popular" + socialIcons = [ + {name = "twitter", url = "https://example.com"}, + {name = "linkedin", url = "https://example.com"}, + {name = "stackoverflow", url = "https://example.com"}, + {name = "dribbble", url = "https://example.com"}, + {name = "instagram", url = "https://example.com"}, + {name = "twitch", url = "https://example.com"}, + ] metaKeywords = ["blog", "gokarna", "hugo"] [menu] @@ -45,16 +52,16 @@ pygmentsStyle = "monokai" url = "/tags/" weight = 4 - [[menu.main]] - identifier = "coffee" - pre = "" - url = "https://www.buymeacoffee.com/avijitgupta" - weight = 5 - [[menu.main]] identifier = "github" pre = "" url = "https://github.com/526avijitgupta/gokarna" + weight = 5 + + [[menu.main]] + identifier = "buymeacoffee" + pre = "" + url = "https://www.buymeacoffee.com/avijitgupta" weight = 6 [[menu.main]] diff --git a/exampleSite/content/posts/theme-documentation-advanced.md b/exampleSite/content/posts/theme-documentation-advanced.md index 26c00b3..aba24b8 100644 --- a/exampleSite/content/posts/theme-documentation-advanced.md +++ b/exampleSite/content/posts/theme-documentation-advanced.md @@ -11,7 +11,7 @@ Gokarna is an opinionated theme with a focus on minimalism and simplicity. ## Content Types -This theme supports two types of content types: `post` and `page`. To specify them, you need to add them in your markdown metadata. +This theme supports two types of content types: `post` and `page`. To specify them, you need to add them in your markdown metadata. ### Post @@ -54,20 +54,54 @@ The `weight` attribute can be added in the markdown metadata for `post` types. W 2. Show recent posts on home page if the value is set to `recent` 3. Do not show anything if the variable is unset or an empty string. -## Icons in header +## Icons +Gokarna supports popular social media icons (Github, Linkedin, Twitter, StackOverflow, Dribbble, etc.) out of the box. See full list of supported icons [here](https://github.com/526avijitgupta/gokarna/tree/main/static/icons). -We have used [feather](https://feathericons.com) as our icons library. Here is an example of how to add custom icons in the header: +### Icons on homepage +To display icons on the homepage, simply update the `socialIcons` config param with a list of name and url of each icon. The specified `name` should exactly match one of the names from [here](https://github.com/526avijitgupta/gokarna/tree/main/static/icons). +If you want to add more icons, you can download the svg directly from [here](https://simpleicons.org/) and place them in your local icons directory (`/static/icons/`) + +```toml + [params] + socialIcons = [ + {name = "twitter", url = "https://example.com"}, + {name = "linkedin", url = "https://example.com"}, + {name = "stackoverflow", url = "https://example.com"}, + ] ``` + +Preview: + +![Icons on homepage Preview](/images/theme-documentation-advanced/icons-homepage-preview.png "Icons on homepage Preview") + + +### Icons in header + +[Feather](https://feathericons.com) icons has a comprehensive list of icons which are more general purpose and not limited to social media. +Therefore, we use feather as an additional source of icons. Here is an example of how to add custom icons in the header using feather: + +```toml [[menu.main]] identifier = "github" url = "https://github.com" weight = 3 - - # We use feather-icons + # Using feather-icons pre = "" ``` +The same icon in this case could also be added without feather: + +```toml + [[menu.main]] + identifier = "github" + url = "https://www.buymeacoffee.com/" + weight = 3 + # Without using feather-icons + pre = "" +``` + + ## Custom Head HTML The goal of this feature is to give the user more control over the theme. It's functioning is very straightforward - "You can inject any HTML you want in the `` tag" . This may seem simple at first, but it opens up a lot of possibilities. @@ -92,7 +126,7 @@ We preferred privacy friendly tools like [Umami](https://umami.is/) & [Fathom An Giving users the freedom to add anything in the HTML via config.toml seemed like an elegant way to solve the problem. -```markdown +```toml [params] customHeadHTML = """ @@ -103,7 +137,7 @@ Giving users the freedom to add anything in the HTML via config.toml seemed like Katex is a math typesetting library for the web which lets you write beautiful equations. To use it, add the javascript as mentioned in [their documentation](https://katex.org/docs/browser.html) in our `params.customHeadHTML`. -```markdown +```toml [params] customHeadHTML = """ diff --git a/exampleSite/static/images/theme-documentation-advanced/icons-homepage-preview.png b/exampleSite/static/images/theme-documentation-advanced/icons-homepage-preview.png new file mode 100644 index 0000000..c4b95df Binary files /dev/null and b/exampleSite/static/images/theme-documentation-advanced/icons-homepage-preview.png differ diff --git a/images/screenshot-dark-home.png b/images/screenshot-dark-home.png index 73e3903..cd0c783 100644 Binary files a/images/screenshot-dark-home.png and b/images/screenshot-dark-home.png differ diff --git a/images/screenshot-dark-list.png b/images/screenshot-dark-list.png index 1518ae1..4eb1967 100644 Binary files a/images/screenshot-dark-list.png and b/images/screenshot-dark-list.png differ diff --git a/images/screenshot-dark-post.png b/images/screenshot-dark-post.png index b066bcb..fa8450b 100644 Binary files a/images/screenshot-dark-post.png and b/images/screenshot-dark-post.png differ diff --git a/images/screenshot-light-home.png b/images/screenshot-light-home.png index 26b5ba9..42990a0 100644 Binary files a/images/screenshot-light-home.png and b/images/screenshot-light-home.png differ diff --git a/images/screenshot-light-list.png b/images/screenshot-light-list.png index b2fa894..072a299 100644 Binary files a/images/screenshot-light-list.png and b/images/screenshot-light-list.png differ diff --git a/images/screenshot-light-post.png b/images/screenshot-light-post.png index 70bc602..06aca8c 100644 Binary files a/images/screenshot-light-post.png and b/images/screenshot-light-post.png differ diff --git a/images/screenshot.png b/images/screenshot.png index 6707d66..b48e1e0 100644 Binary files a/images/screenshot.png and b/images/screenshot.png differ diff --git a/images/tn.png b/images/tn.png index 6707d66..b48e1e0 100644 Binary files a/images/tn.png and b/images/tn.png differ diff --git a/layouts/index.html b/layouts/index.html index 10d9632..5ce5656 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -11,6 +11,20 @@
+{{ if isset .Site.Params "socialicons" }} +
+ +
+{{ end }} + {{ if isset .Site.Params "showpostsonhomepage" }}
diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 1471b27..c62827f 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -40,6 +40,7 @@ + diff --git a/static/css/dark.css b/static/css/dark.css index ac9adbc..66b871e 100644 --- a/static/css/dark.css +++ b/static/css/dark.css @@ -7,6 +7,7 @@ html { background-color: rgb(var(--dark-primary-color)); color: var(--dark-text-color); + fill: var(--dark-text-color); } .header { @@ -26,6 +27,10 @@ a:hover .feather-moon { color: white; } +.social-icons-list .social-icon { + fill: var(--dark-text-color); +} + .post-tags .post-tag:hover { background-color: var(--dark-text-color); color: rgb(var(--dark-primary-color)); diff --git a/static/css/main.css b/static/css/main.css index 7aa4888..1530dd8 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -43,6 +43,7 @@ a { /* This is set in partials/head.html and is populated via config */ a:hover { color: var(--accent-color); + fill: var(--accent-color); } main#content { @@ -112,6 +113,12 @@ img { display: block; padding: 0 6px; } +.nav-link a svg { + height: 20px; + margin: -3px auto; + stroke-width: 2; + width: 20px; +} .nav-links .nav-link.icon a { padding: 0 8px; } @@ -196,14 +203,6 @@ a:hover .feather-sun { box-shadow: rgb(220, 220, 220) 0px 1px 5px; } -/* ICONS */ -.feather { - height: 20px; - margin: -3px auto; - stroke-width: 2; - width: 20px; -} - /* TAGS */ .post-tags { list-style-type: none; @@ -329,6 +328,30 @@ table td { width: 15rem; } +.social-icons { + text-align: center; +} + +.social-icons .social-icons-list { + display: inline-block; + list-style-type: none; + padding: 0; + text-align: center; +} + +.social-icons-list .social-icon { + box-sizing: border-box; + display: inline-block; + fill: var(--light-text-color); + height: 24px; + margin: 0 6px; + width: 24px; +} + +.social-icon a svg path { + transition: fill 0.15s ease; +} + .home-posts { padding-top: 20px; } diff --git a/static/icons/angellist.svg b/static/icons/angellist.svg new file mode 100644 index 0000000..7cce259 --- /dev/null +++ b/static/icons/angellist.svg @@ -0,0 +1 @@ +AngelList \ No newline at end of file diff --git a/static/icons/buymeacoffee.svg b/static/icons/buymeacoffee.svg new file mode 100644 index 0000000..5187886 --- /dev/null +++ b/static/icons/buymeacoffee.svg @@ -0,0 +1 @@ +Buy Me A Coffee \ No newline at end of file diff --git a/static/icons/dribbble.svg b/static/icons/dribbble.svg new file mode 100644 index 0000000..130a6f5 --- /dev/null +++ b/static/icons/dribbble.svg @@ -0,0 +1 @@ +Dribbble \ No newline at end of file diff --git a/static/icons/facebook.svg b/static/icons/facebook.svg new file mode 100644 index 0000000..4ef9d67 --- /dev/null +++ b/static/icons/facebook.svg @@ -0,0 +1 @@ +Facebook \ No newline at end of file diff --git a/static/icons/github.svg b/static/icons/github.svg new file mode 100644 index 0000000..538ec5b --- /dev/null +++ b/static/icons/github.svg @@ -0,0 +1 @@ +GitHub \ No newline at end of file diff --git a/static/icons/gmail.svg b/static/icons/gmail.svg new file mode 100644 index 0000000..9ee779a --- /dev/null +++ b/static/icons/gmail.svg @@ -0,0 +1 @@ +Gmail \ No newline at end of file diff --git a/static/icons/google.svg b/static/icons/google.svg new file mode 100644 index 0000000..2eaf915 --- /dev/null +++ b/static/icons/google.svg @@ -0,0 +1 @@ +Google \ No newline at end of file diff --git a/static/icons/instagram.svg b/static/icons/instagram.svg new file mode 100644 index 0000000..5a68721 --- /dev/null +++ b/static/icons/instagram.svg @@ -0,0 +1 @@ +Instagram \ No newline at end of file diff --git a/static/icons/kofi.svg b/static/icons/kofi.svg new file mode 100644 index 0000000..1c209d9 --- /dev/null +++ b/static/icons/kofi.svg @@ -0,0 +1 @@ +Ko-fi \ No newline at end of file diff --git a/static/icons/linkedin.svg b/static/icons/linkedin.svg new file mode 100644 index 0000000..caa6e69 --- /dev/null +++ b/static/icons/linkedin.svg @@ -0,0 +1 @@ +LinkedIn \ No newline at end of file diff --git a/static/icons/mastodon.svg b/static/icons/mastodon.svg new file mode 100644 index 0000000..19141c7 --- /dev/null +++ b/static/icons/mastodon.svg @@ -0,0 +1 @@ +Mastodon \ No newline at end of file diff --git a/static/icons/mozilla.svg b/static/icons/mozilla.svg new file mode 100644 index 0000000..507eb66 --- /dev/null +++ b/static/icons/mozilla.svg @@ -0,0 +1 @@ +Mozilla \ No newline at end of file diff --git a/static/icons/reddit.svg b/static/icons/reddit.svg new file mode 100644 index 0000000..7e4ddd1 --- /dev/null +++ b/static/icons/reddit.svg @@ -0,0 +1 @@ +Reddit \ No newline at end of file diff --git a/static/icons/rss.svg b/static/icons/rss.svg new file mode 100644 index 0000000..14a6f3f --- /dev/null +++ b/static/icons/rss.svg @@ -0,0 +1 @@ +RSS \ No newline at end of file diff --git a/static/icons/spotify.svg b/static/icons/spotify.svg new file mode 100644 index 0000000..8d4d095 --- /dev/null +++ b/static/icons/spotify.svg @@ -0,0 +1 @@ +Spotify \ No newline at end of file diff --git a/static/icons/stackoverflow.svg b/static/icons/stackoverflow.svg new file mode 100644 index 0000000..ab83808 --- /dev/null +++ b/static/icons/stackoverflow.svg @@ -0,0 +1 @@ +Stack Overflow \ No newline at end of file diff --git a/static/icons/tiktok.svg b/static/icons/tiktok.svg new file mode 100644 index 0000000..57ce3ae --- /dev/null +++ b/static/icons/tiktok.svg @@ -0,0 +1 @@ +TikTok \ No newline at end of file diff --git a/static/icons/twitch.svg b/static/icons/twitch.svg new file mode 100644 index 0000000..8aaa4a9 --- /dev/null +++ b/static/icons/twitch.svg @@ -0,0 +1 @@ +Twitch \ No newline at end of file diff --git a/static/icons/twitter.svg b/static/icons/twitter.svg new file mode 100644 index 0000000..45bd20c --- /dev/null +++ b/static/icons/twitter.svg @@ -0,0 +1 @@ +Twitter \ No newline at end of file diff --git a/static/icons/vimeo.svg b/static/icons/vimeo.svg new file mode 100644 index 0000000..cecbfcc --- /dev/null +++ b/static/icons/vimeo.svg @@ -0,0 +1 @@ +Vimeo \ No newline at end of file diff --git a/static/icons/xing.svg b/static/icons/xing.svg new file mode 100644 index 0000000..43e874a --- /dev/null +++ b/static/icons/xing.svg @@ -0,0 +1 @@ +Xing \ No newline at end of file diff --git a/static/icons/ycombinator.svg b/static/icons/ycombinator.svg new file mode 100644 index 0000000..8eb0d25 --- /dev/null +++ b/static/icons/ycombinator.svg @@ -0,0 +1 @@ +Y Combinator \ No newline at end of file diff --git a/static/icons/youtube.svg b/static/icons/youtube.svg new file mode 100644 index 0000000..0492366 --- /dev/null +++ b/static/icons/youtube.svg @@ -0,0 +1 @@ +YouTube \ No newline at end of file diff --git a/static/js/main.js b/static/js/main.js index ae2274f..3169e1e 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -12,6 +12,11 @@ function ready() { feather.replace({ 'stroke-width': 1, width: 20, height: 20 }); setThemeByUserPref(); + // Elements to inject + const svgsToInject = document.querySelectorAll('img.svg-inject'); + // Do the injection + SVGInjector(svgsToInject); + document.getElementById('hamburger-menu-toggle').addEventListener('click', () => { const hamburgerMenu = document.getElementsByClassName('nav-hamburger-list')[0] if (hamburgerMenu.classList.contains('visibility-hidden')) { diff --git a/static/js/svg-injector.min.js b/static/js/svg-injector.min.js new file mode 100644 index 0000000..243424b --- /dev/null +++ b/static/js/svg-injector.min.js @@ -0,0 +1,9 @@ +/** + * SVGInjector v1.1.3 - Fast, caching, dynamic inline SVG DOM injection library + * https://github.com/iconic/SVGInjector + * + * Copyright (c) 2014-2015 Waybury + * @license MIT + */ +!function(t,e){"use strict";function r(t){t=t.split(" ");for(var e={},r=t.length,n=[];r--;)e.hasOwnProperty(t[r])||(e[t[r]]=1,n.unshift(t[r]));return n.join(" ")}var n="file:"===t.location.protocol,i=e.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"),o=Array.prototype.forEach||function(t,e){if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;var r,n=this.length>>>0;for(r=0;n>r;++r)r in this&&t.call(e,this[r],r,this)},a={},l=0,s=[],u=[],c={},f=function(t){return t.cloneNode(!0)},p=function(t,e){u[t]=u[t]||[],u[t].push(e)},d=function(t){for(var e=0,r=u[t].length;r>e;e++)!function(e){setTimeout(function(){u[t][e](f(a[t]))},0)}(e)},v=function(e,r){if(void 0!==a[e])a[e]instanceof SVGSVGElement?r(f(a[e])):p(e,r);else{if(!t.XMLHttpRequest)return r("Browser does not support XMLHttpRequest"),!1;a[e]={},p(e,r);var i=new XMLHttpRequest;i.onreadystatechange=function(){if(4===i.readyState){if(404===i.status||null===i.responseXML)return r("Unable to load SVG file: "+e),n&&r("Note: SVG injection ajax calls do not work locally without adjusting security setting in your browser. Or consider using a local webserver."),r(),!1;if(!(200===i.status||n&&0===i.status))return r("There was a problem injecting the SVG: "+i.status+" "+i.statusText),!1;if(i.responseXML instanceof Document)a[e]=i.responseXML.documentElement;else if(DOMParser&&DOMParser instanceof Function){var t;try{var o=new DOMParser;t=o.parseFromString(i.responseText,"text/xml")}catch(l){t=void 0}if(!t||t.getElementsByTagName("parsererror").length)return r("Unable to parse SVG file: "+e),!1;a[e]=t.documentElement}d(e)}},i.open("GET",e),i.overrideMimeType&&i.overrideMimeType("text/xml"),i.send()}},h=function(e,n,a,u){var f=e.getAttribute("data-src")||e.getAttribute("src");if(!/\.svg/i.test(f))return void u("Attempted to inject a file with a non-svg extension: "+f);if(!i){var p=e.getAttribute("data-fallback")||e.getAttribute("data-png");return void(p?(e.setAttribute("src",p),u(null)):a?(e.setAttribute("src",a+"/"+f.split("/").pop().replace(".svg",".png")),u(null)):u("This browser does not support SVG and no PNG fallback was defined."))}-1===s.indexOf(e)&&(s.push(e),e.setAttribute("src",""),v(f,function(i){if("undefined"==typeof i||"string"==typeof i)return u(i),!1;var a=e.getAttribute("id");a&&i.setAttribute("id",a);var p=e.getAttribute("title");p&&i.setAttribute("title",p);var d=[].concat(i.getAttribute("class")||[],"injected-svg",e.getAttribute("class")||[]).join(" ");i.setAttribute("class",r(d));var v=e.getAttribute("style");v&&i.setAttribute("style",v);var h=[].filter.call(e.attributes,function(t){return/^data-\w[\w\-]*$/.test(t.name)});o.call(h,function(t){t.name&&t.value&&i.setAttribute(t.name,t.value)});var g,m,b,y,A,w={clipPath:["clip-path"],"color-profile":["color-profile"],cursor:["cursor"],filter:["filter"],linearGradient:["fill","stroke"],marker:["marker","marker-start","marker-mid","marker-end"],mask:["mask"],pattern:["fill","stroke"],radialGradient:["fill","stroke"]};Object.keys(w).forEach(function(t){g=t,b=w[t],m=i.querySelectorAll("defs "+g+"[id]");for(var e=0,r=m.length;r>e;e++){y=m[e].id,A=y+"-"+l;var n;o.call(b,function(t){n=i.querySelectorAll("["+t+'*="'+y+'"]');for(var e=0,r=n.length;r>e;e++)n[e].setAttribute(t,"url(#"+A+")")}),m[e].id=A}}),i.removeAttribute("xmlns:a");for(var x,S,k=i.querySelectorAll("script"),j=[],G=0,T=k.length;T>G;G++)S=k[G].getAttribute("type"),S&&"application/ecmascript"!==S&&"application/javascript"!==S||(x=k[G].innerText||k[G].textContent,j.push(x),i.removeChild(k[G]));if(j.length>0&&("always"===n||"once"===n&&!c[f])){for(var M=0,V=j.length;V>M;M++)new Function(j[M])(t);c[f]=!0}var E=i.querySelectorAll("style");o.call(E,function(t){t.textContent+=""}),e.parentNode.replaceChild(i,e),delete s[s.indexOf(e)],e=null,l++,u(i)}))},g=function(t,e,r){e=e||{};var n=e.evalScripts||"always",i=e.pngFallback||!1,a=e.each;if(void 0!==t.length){var l=0;o.call(t,function(e){h(e,n,i,function(e){a&&"function"==typeof a&&a(e),r&&t.length===++l&&r(l)})})}else t?h(t,n,i,function(e){a&&"function"==typeof a&&a(e),r&&r(1),t=null}):r&&r(0)};"object"==typeof module&&"object"==typeof module.exports?module.exports=exports=g:"function"==typeof define&&define.amd?define(function(){return g}):"object"==typeof t&&(t.SVGInjector=g)}(window,document); +//# sourceMappingURL=svg-injector.map.js \ No newline at end of file