feat: add embed shortcode

Embed GitHub repos, HuggingFace, and custom providers

See Academic CV demo blog for examples
This commit is contained in:
George Cushen committed 2025-09-07 23:04:43 +01:00
1 parent 21a72ba522
commit 1675dd45f0
16 files changed
+1065 -11

No files matched your search

+5 -2
View File
@@ -17,6 +17,9 @@ icons:
google-scholar: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M343.759 106.662V79.43L363.524 64h-213.89L20.476 176.274h85.656a82.339 82.339 0 0 0-.219 6.225c0 20.845 7.22 38.087 21.672 51.861 14.453 13.797 32.252 20.648 53.327 20.648 4.923 0 9.75-.368 14.438-1.024-2.907 6.5-4.374 12.523-4.374 18.142 0 9.875 4.499 20.43 13.467 31.642-39.234 2.67-68.061 9.732-86.437 21.163-10.531 6.5-19 14.704-25.39 24.531-6.391 9.9-9.578 20.515-9.578 31.962 0 9.648 2.062 18.336 6.219 26.062 4.156 7.726 9.578 14.07 16.312 18.984 6.718 4.968 14.469 9.101 23.219 12.469 8.734 3.344 17.406 5.718 26.061 7.062A167.052 167.052 0 0 0 180.555 448c13.469 0 26.953-1.734 40.547-5.187 13.562-3.485 26.28-8.642 38.171-15.493 11.86-6.805 21.515-16.086 28.922-27.718 7.39-11.68 11.094-24.805 11.094-39.336 0-11.016-2.25-21.039-6.75-30.14-4.468-9.073-9.938-16.542-16.452-22.345-6.501-5.813-13-11.155-19.516-15.968-6.5-4.845-12-9.75-16.468-14.813-4.485-5.046-6.735-10.054-6.735-14.984 0-4.921 1.734-9.672 5.216-14.265 3.455-4.61 7.674-9.048 12.61-13.306 4.937-4.25 9.875-8.968 14.796-14.133 4.922-5.147 9.141-11.827 12.61-20.008 3.485-8.18 5.203-17.445 5.203-27.757 0-13.453-2.547-24.46-7.547-33.314-.594-1.022-1.218-1.803-1.875-3.022l56.907-46.672v17.119c-7.393.93-6.624 5.345-6.624 10.635V245.96c0 5.958 4.875 10.834 10.834 10.834h3.989c5.958 0 10.833-4.875 10.833-10.834V117.293c0-5.277.778-9.688-6.561-10.63zm-107.36 222.48c1.14.75 3.704 2.78 7.718 6.038 4.05 3.243 6.797 5.695 8.266 7.414a443.553 443.553 0 0 1 6.376 7.547c2.813 3.375 4.718 6.304 5.718 8.734 1 2.477 2.016 5.461 3.047 8.946a38.27 38.27 0 0 1 1.485 10.562c0 17.048-6.564 29.68-19.656 37.859-13.125 8.18-28.767 12.274-46.938 12.274-9.187 0-18.203-1.093-27.063-3.196-8.843-2.116-17.311-5.336-25.39-9.601-8.078-4.258-14.577-10.204-19.5-17.797-4.938-7.64-7.407-16.415-7.407-26.25 0-10.32 2.797-19.29 8.422-26.906 5.594-7.625 12.938-13.391 22.032-17.315 9.063-3.946 18.25-6.742 27.562-8.398a157.865 157.865 0 0 1 28.438-2.555c4.47 0 7.936.25 10.405.696.455.219 3.032 2.07 7.735 5.563 4.704 3.462 7.625 5.595 8.75 6.384zm-3.359-100.579c-7.406 8.86-17.734 13.288-30.953 13.288-11.86 0-22.298-4.764-31.266-14.312-9-9.523-15.422-20.328-19.344-32.43-3.937-12.109-5.906-23.984-5.906-35.648 0-13.694 3.596-25.352 10.781-34.976 7.187-9.65 17.5-14.485 30.938-14.485 11.875 0 22.374 5.038 31.437 15.157 9.094 10.085 15.61 21.413 19.517 33.968 3.922 12.54 5.873 24.53 5.873 35.984 0 13.446-3.702 24.61-11.076 33.454z" style="stroke-width:.0647871"/></svg>
orcid: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 512 512"><path d="M336.62 194.538c-7.13-3.328-13.866-5.56-20.253-6.614-6.365-1.095-16.574-1.612-30.71-1.612h-36.704v152.747h37.634c14.673 0 26.081-1.013 34.224-3.017 8.142-2.004 14.921-4.526 20.356-7.626a69.448 69.448 0 0 0 14.942-11.388c14.488-14.714 21.742-33.273 21.742-55.717 0-22.052-7.44-40.052-22.341-53.982-5.498-5.166-11.822-9.444-18.89-12.793zM256 8C119.022 8 8 119.042 8 256s111.022 248 248 248 248-111.042 248-248S392.978 8 256 8Zm-82.336 357.513h-29.389V160.148h29.389zM158.95 138.696c-11.14 0-20.213-9.01-20.213-20.212 0-11.118 9.052-20.191 20.213-20.191 11.18 0 20.232 9.052 20.232 20.191a20.194 20.194 0 0 1-20.232 20.212zm241.386 163.597c-5.29 12.545-12.834 23.581-22.65 33.088-9.982 9.837-21.597 17.194-34.844 22.196-7.75 3.017-14.839 5.063-21.307 6.117-6.49 1.013-18.828 1.509-37.076 1.509h-64.956V160.148h69.233c27.962 0 50.034 4.154 66.32 12.545 16.265 8.37 29.181 20.728 38.792 36.972 9.61 16.265 14.425 34.018 14.425 53.196.023 13.765-2.666 26.908-7.936 39.432z" style="stroke-width:.07717"/></svg>
reddit: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 28.901 28.901"><path d="M28.901,13.375v0.183c0,0.66-0.2,1.261-0.598,1.803c-0.374,0.519-0.842,0.915-1.405,1.191 c0.021,0.119,0.039,0.248,0.051,0.387c0.013,0.14,0.021,0.278,0.021,0.425c0,1.431-0.481,2.723-1.443,3.879 c-0.844,1.034-1.865,1.866-3.068,2.498c-1.204,0.631-2.459,1.104-3.77,1.415c-0.71,0.146-1.416,0.262-2.123,0.353 c-0.702,0.091-1.408,0.137-2.117,0.137c-1.082,0-2.147-0.095-3.194-0.282c-1.044-0.187-2.061-0.465-3.047-0.838 c-1.034-0.397-2.015-0.909-2.94-1.533c-0.929-0.625-1.697-1.407-2.31-2.347c-0.325-0.491-0.571-1.021-0.74-1.586 c-0.169-0.566-0.254-1.13-0.254-1.695c0-0.121,0.008-0.249,0.019-0.389c0.014-0.138,0.028-0.267,0.055-0.387 c-0.59-0.325-1.048-0.725-1.371-1.191C0.245,14.831,0.021,14.24,0,13.629c0-0.445,0.097-0.868,0.297-1.273 c0.199-0.403,0.458-0.767,0.783-1.091c0.348-0.324,0.73-0.577,1.147-0.757c0.414-0.182,0.868-0.271,1.359-0.271h0.037h0.289 c0.494,0,0.962,0.073,1.405,0.217c0.423,0.144,0.807,0.343,1.157,0.596c0.046-0.024,0.101-0.049,0.162-0.072 c0.059-0.024,0.125-0.049,0.197-0.074c1.037-0.564,2.143-0.975,3.328-1.235c1.186-0.257,2.367-0.43,3.545-0.512 c0-0.544,0.049-1.089,0.146-1.642c0.095-0.553,0.294-1.078,0.595-1.569c0.24-0.423,0.553-0.78,0.939-1.076 c0.384-0.293,0.821-0.501,1.315-0.621h0.036c0.374-0.072,0.738-0.107,1.101-0.107c0.964,0,1.938,0.196,2.923,0.595 c0.397-0.587,0.947-1.024,1.662-1.299h0.033c0.445-0.123,0.868-0.184,1.265-0.184c0.494,0,0.927,0.085,1.298,0.254h0.038 c0.587,0.216,1.081,0.583,1.479,1.1c0.396,0.542,0.591,1.126,0.579,1.749c0,0.146-0.014,0.254-0.036,0.327 c-0.049,0.42-0.169,0.795-0.362,1.127c-0.193,0.33-0.439,0.622-0.74,0.873c-0.663,0.543-1.413,0.812-2.255,0.812h-0.413 c-0.844-0.07-1.552-0.401-2.131-0.989c-0.276-0.277-0.498-0.588-0.665-0.93c-0.169-0.344-0.254-0.726-0.254-1.146v-0.11 c-0.396-0.144-0.793-0.273-1.193-0.388c-0.395-0.112-0.806-0.172-1.225-0.172h-0.325c-0.686,0.071-1.167,0.381-1.443,0.922 c-0.216,0.371-0.358,0.774-0.423,1.208c-0.066,0.434-0.103,0.866-0.103,1.299c1.184,0.072,2.339,0.246,3.476,0.523 c1.137,0.274,2.225,0.685,3.255,1.227l0.037,0.036c0.047,0,0.098,0.023,0.145,0.072c0.194-0.146,0.355-0.247,0.486-0.306 c0.611-0.398,1.316-0.59,2.112-0.579c0.301,0,0.62,0.036,0.956,0.109h0.036c0.731,0.193,1.377,0.57,1.93,1.135 C28.52,11.961,28.829,12.619,28.901,13.375z M4.885,12.076c-0.169-0.047-0.327-0.095-0.476-0.144 c-0.15-0.049-0.317-0.071-0.496-0.071H3.767H3.733c-0.445,0.048-0.866,0.22-1.262,0.523c-0.352,0.322-0.54,0.703-0.579,1.137v0.108 c0,0.3,0.085,0.546,0.254,0.74c0.118,0.216,0.259,0.376,0.415,0.486c0.274-0.541,0.609-1.041,0.998-1.499 C3.951,12.9,4.395,12.474,4.885,12.076z M25.129,17.4c0-0.494-0.087-0.968-0.262-1.427c-0.177-0.456-0.406-0.889-0.693-1.298 c-0.618-0.796-1.364-1.449-2.257-1.969c-0.891-0.515-1.828-0.911-2.814-1.189l-0.578-0.145l-0.559-0.143 c-0.563-0.122-1.145-0.212-1.741-0.272c-0.594-0.06-1.175-0.091-1.738-0.091c-1.626,0-3.178,0.219-4.656,0.65 c-0.988,0.278-1.92,0.68-2.807,1.209c-0.884,0.529-1.639,1.189-2.263,1.983c-0.639,0.796-0.956,1.703-0.956,2.726 c0,0.397,0.047,0.739,0.144,1.029c0.219,0.758,0.615,1.459,1.193,2.11c0.566,0.565,1.211,1.081,1.945,1.55l0.272,0.127l0.254,0.146 c1.034,0.541,2.136,0.936,3.309,1.181c1.172,0.247,2.36,0.37,3.564,0.37h0.612c0.201,0,0.409-0.01,0.612-0.037 c1.203-0.097,2.383-0.317,3.536-0.667c1.154-0.348,2.225-0.854,3.211-1.515c0.663-0.469,1.203-0.986,1.623-1.552 c0.495-0.613,0.819-1.269,0.976-1.967c0.047-0.12,0.072-0.247,0.072-0.378L25.129,17.4L25.129,17.4z M9.415,17.579 c0.169,0.071,0.354,0.107,0.56,0.107c0.468,0,0.891-0.156,1.263-0.47c0.398-0.323,0.596-0.721,0.596-1.188V15.99v-0.072 c0-0.443-0.187-0.822-0.559-1.135c-0.396-0.325-0.832-0.488-1.3-0.488c-0.145,0-0.267,0.011-0.359,0.037 c-0.325,0.048-0.612,0.176-0.857,0.388c-0.249,0.21-0.418,0.466-0.516,0.768c-0.049,0.07-0.073,0.149-0.073,0.233v0.236 c0,0.396,0.109,0.744,0.327,1.046C8.736,17.292,9.041,17.483,9.415,17.579z M19.518,19.764c-0.189-0.098-0.353-0.146-0.486-0.146 c-0.143,0-0.297,0.036-0.451,0.11c-1.31,0.733-2.737,1.105-4.276,1.117c-1.154,0-2.225-0.222-3.211-0.667 c-0.143-0.049-0.319-0.162-0.522-0.343c-0.049-0.024-0.102-0.046-0.161-0.071c-0.061-0.024-0.123-0.049-0.183-0.071 c-0.143-0.049-0.252-0.075-0.325-0.075c-0.071,0-0.181,0.026-0.324,0.075h-0.04c-0.144,0.047-0.28,0.153-0.413,0.323 c-0.071,0.12-0.107,0.271-0.107,0.451c0,0.144,0.036,0.294,0.107,0.449c0.072,0.122,0.182,0.218,0.326,0.289 c1.383,0.867,2.896,1.301,4.545,1.301c0.085,0,0.177,0,0.269,0c0.794,0,1.565-0.076,2.31-0.226c0.746-0.15,1.47-0.389,2.167-0.712 c0.095-0.049,0.197-0.098,0.308-0.146c0.107-0.047,0.222-0.107,0.34-0.179c0.123-0.05,0.226-0.121,0.311-0.217 c0.118-0.119,0.189-0.247,0.215-0.381c0.025-0.047,0.038-0.106,0.038-0.179c0-0.071-0.025-0.181-0.076-0.325 C19.805,19.96,19.685,19.834,19.518,19.764z M20.652,15.449c0.075,0.193,0.11,0.374,0.11,0.541c0,0.373-0.11,0.711-0.326,1.013 c-0.299,0.323-0.606,0.516-0.919,0.576h-0.053c-0.193,0.071-0.362,0.107-0.505,0.107c-0.449,0-0.843-0.131-1.191-0.395 c-0.35-0.218-0.561-0.536-0.635-0Line truncated
# Hugo
# AI/ML Platforms
huggingface: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 475 439"><path d="M235.793 396.126a187.281 187.281 0 00187.285-187.284A187.283 187.283 0 00235.793 21.558 187.287 187.287 0 0048.509 208.842a187.286 187.286 0 00187.284 187.284z" fill="#FFD21E"/><path d="M423.078 208.842A187.283 187.283 0 00235.793 21.558 187.283 187.283 0 0048.509 208.842a187.283 187.283 0 00319.714 132.43 187.284 187.284 0 0054.855-132.43zm-396.127 0a208.842 208.842 0 11417.685 0 208.842 208.842 0 01-417.685 0z" fill="#FF9D0B"/><path d="M296.641 157.912c6.898 2.371 9.593 16.491 16.545 12.827a26.946 26.946 0 008.24-40.841 26.952 26.952 0 00-28.632-8.767 26.942 26.942 0 00-19.055 23.099 26.943 26.943 0 003.014 15.352c3.288 6.198 13.744-3.88 19.941-1.724l-.053.054zm-126.923 0c-6.898 2.371-9.647 16.491-16.545 12.827a26.946 26.946 0 01-8.24-40.841 26.952 26.952 0 0128.632-8.767 26.944 26.944 0 0116.041 38.451c-3.288 6.198-13.797-3.88-19.941-1.724l.053.054z" fill="#3A3B45"/><path d="M234.446 287.205c52.979 0 70.063-47.212 70.063-71.464 0-12.612-8.461-8.624-22.043-1.941-12.557 6.198-29.426 14.768-47.966 14.768-38.75 0-70.063-37.08-70.063-12.827 0 24.252 17.031 71.464 70.063 71.464h-.054z" fill="#FF323D"/></svg>
# Development
hugo: <svg viewBox="0 0 370 391" xmlns="http://www.w3.org/2000/svg"><g clip-rule="evenodd" fill-rule="evenodd"><path d="m207.5 22.4 114.4 66.6c13.5 7.9 21.9 22.4 21.9 38v136.4c0 17.3-9.3 33.3-24.5 41.8l-113.5 63.9a49.06 49.06 0 0 1 -48.5-.2l-104.5-60.1c-16.4-9.5-26.6-27-26.6-45.9v-129.5c0-19.1 9.9-36.8 26.1-46.8l102.8-63.5c16-9.9 36.2-10.1 52.4-.7z" fill="#ff4088" stroke="#c9177e" stroke-width="27" /><path d="m105.6 298.2v-207.2h43.4v75.5h71.9v-75.5h43.5v207.2h-43.5v-90.6h-71.9v90.6z" fill="#fff" /></g></svg>
+8 -3
View File
@@ -13,14 +13,19 @@ icons:
card: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M14 11V4H1v7h13Zm1-7v7a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h13a1 1 0 0 1 1 1ZM2 5.25A.25.25 0 0 1 2.25 5h3.5a.25.25 0 0 1 .25.25v4.5a.25.25 0 0 1-.25.25h-3.5A.25.25 0 0 1 2 9.75v-4.5ZM7.5 7a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3ZM7 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5ZM7.5 5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4Z" clip-rule="evenodd"/></svg>
folder-tree: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="m 114.47781,81.538059 c 0,-13.785609 -11.07754,-24.923135 -24.78889,-24.923135 -13.711352,0 -24.788885,11.137526 -24.788885,24.923135 V 355.69254 c 0,27.49333 22.232532,49.84627 49.577775,49.84627 H 263.21112 V 355.69254 H 114.47781 V 181.2306 H 263.21112 V 131.38433 H 114.47781 Z M 288,206.15373 c 0,13.78561 11.07753,24.92314 24.78888,24.92314 h 173.5222 c 13.71135,0 24.78888,-11.13753 24.78888,-24.92314 v -99.69254 c 0,-13.785605 -11.07753,-24.923131 -24.78888,-24.923131 h -76.45822 c -6.58454,0 -12.85923,-2.648083 -17.50715,-7.321171 L 382.04283,63.936095 c -4.64791,-4.673088 -10.9226,-7.321171 -17.50715,-7.321171 h -51.7468 C 299.07753,56.614924 288,67.75245 288,81.538059 Z m 0,224.30821 c 0,13.78561 11.07753,24.92314 24.78888,24.92314 h 173.5222 c 13.71135,0 24.78888,-11.13753 24.78888,-24.92314 V 330.7694 c 0,-13.78561 -11.07753,-24.92313 -24.78888,-24.92313 h -76.45822 c -6.58454,0 -12.85923,-2.64808 -17.50715,-7.32117 l -10.30288,-10.35868 c -4.64791,-4.67309 -10.9226,-7.32117 -17.50715,-7.32117 h -51.7468 C 299.07753,280.84525 288,291.98278 288,305.76838 Z" style="stroke-width:0.776747" /></svg>
one: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="-1 0 19 19"><path d="M16.417 9.6A7.917 7.917 0 1 1 8.5 1.683 7.917 7.917 0 0 1 16.417 9.6zM9.666 6.508H8.248L6.09 8.09l.806 1.103 1.222-.945v4.816h1.547z"></path></svg>
code-bracket: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
code-bracket:
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" />
</svg>
circle-stack: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
circle-stack:
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
</svg>
magnifying-glass: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z" clip-rule="evenodd" /></svg>
# Phosphor icons
cat: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 256 256"><path d="M96,140a12,12,0,1,1-12-12A12,12,0,0,1,96,140Zm76-12a12,12,0,1,0,12,12A12,12,0,0,0,172,128Zm60-80v88c0,52.93-46.65,96-104,96S24,188.93,24,136V48A16,16,0,0,1,51.31,36.69c.14.14.26.27.38.41L69,57a111.22,111.22,0,0,1,118.1,0L204.31,37.1c.12-.14.24-.27.38-.41A16,16,0,0,1,232,48Zm-16,0-21.56,24.8A8,8,0,0,1,183.63,74,88.86,88.86,0,0,0,168,64.75V88a8,8,0,1,1-16,0V59.05a97.43,97.43,0,0,0-16-2.72V88a8,8,0,1,1-16,0V56.33a97.43,97.43,0,0,0-16,2.72V88a8,8,0,1,1-16,0V64.75A88.86,88.86,0,0,0,72.37,74a8,8,0,0,1-10.81-1.17L40,48v88c0,41.66,35.21,76,80,79.67V195.31l-13.66-13.66a8,8,0,0,1,11.32-11.31L128,180.68l10.34-10.34a8,8,0,0,1,11.32,11.31L136,195.31v20.36c44.79-3.69,80-38,80-79.67Z"></path></svg>
person-simple-walk: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 256 256"><path d="M152,80a32,32,0,1,0-32-32A32,32,0,0,0,152,80Zm0-48a16,16,0,1,1-16,16A16,16,0,0,1,152,32Zm64,112a8,8,0,0,1-8,8c-35.31,0-52.95-17.81-67.12-32.12-2.74-2.77-5.36-5.4-8-7.84l-13.43,30.88,37.2,26.57A8,8,0,0,1,160,176v56a8,8,0,0,1-16,0V180.12l-31.07-22.2L79.34,235.19A8,8,0,0,1,72,240a7.84,7.84,0,0,1-3.19-.67,8,8,0,0,1-4.15-10.52l54.08-124.37c-9.31-1.65-20.92,1.2-34.7,8.58a163.88,163.88,0,0,0-30.57,21.77,8,8,0,0,1-10.95-11.66c2.5-2.35,61.69-57.23,98.72-25.08,3.83,3.32,7.48,7,11,10.57C166.19,122.7,179.36,136,208,136A8,8,0,0,1,216,144Z"></path></svg>
person-simple-walk: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 256 256"><path d="M152,80a32,32,0,1,0-32-32A32,32,0,0,0,152,80Zm0-48a16,16,0,1,1-16,16A16,16,0,0,1,152,32Zm64,112a8,8,0,0,1-8,8c-35.31,0-52.95-17.81-67.12-32.12-2.74-2.77-5.36-5.4-8-7.84l-13.43,30.88,37.2,26.57A8,8,0,0,1,160,176v56a8,8,0,0,1-16,0V180.12l-31.07-22.2L79.34,235.19A8,8,0,0,1,72,240a7.84,7.84,0,0,1-3.19-.67,8,8,0,0,1-4.15-10.52l54.08-124.37c-9.31-1.65-20.92,1.2-34.7,8.58a163.88,163.88,0,0,0-30.57,21.77a8,8,0,0,1-10.95-11.66c2.5-2.35,61.69-57.23,98.72-25.08,3.83,3.32,7.48,7,11,10.57C166.19,122.7,179.36,136,208,136A8,8,0,0,1,216,144Z"></path></svg>
# Git icons
git-fork: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M6 2C4.89543 2 4 2.89543 4 4C4 4.74028 4.4022 5.38663 5 5.73244V7C5 8.65685 6.34315 10 8 10H10V11.2676C9.4022 11.6134 9 12.2597 9 13C9 14.1046 9.89543 15 11 15C12.1046 15 13 14.1046 13 13C13 12.2597 12.5978 11.6134 12 11.2676V10H14C15.6569 10 17 8.65685 17 7V5.73244C17.5978 5.38663 18 4.74028 18 4C18 2.89543 17.1046 2 16 2C14.8954 2 14 2.89543 14 4C14 4.74028 14.4022 5.38663 15 5.73244V7C15 7.55228 14.5523 8 14 8H8C7.44772 8 7 7.55228 7 7V5.73244C7.5978 5.38663 8 4.74028 8 4C8 2.89543 7.10457 2 6 2ZM6 4C6 3.44772 6.44772 3 7 3C7.55228 3 8 3.44772 8 4C8 4.55228 7.55228 5 7 5C6.44772 5 6 4.55228 6 4ZM11 13C11 12.4477 11.4477 12 12 12C12.5523 12 13 12.4477 13 13C13 13.5523 12.5523 14 12 14C11.4477 14 11 13.5523 11 13ZM16 3C15.4477 3 15 3.44772 15 4C15 4.55228 15.4477 5 16 5C16.5523 5 17 4.55228 17 4C17 3.44772 16.5523 3 16 3Z"/></svg>
@@ -0,0 +1,97 @@
{{/*
Hugo Blox GitHub Platform Configuration
Part of Hugo Blox embed system
Parameters:
- resource: repository identifier (e.g., "owner/repo")
- type: "repo", "gist", etc.
- user: username/organization
- customUrl: optional override URL
*/}}
{{- $resource := .resource -}}
{{- $type := .type | default "repo" -}}
{{- $user := .user -}}
{{- $customUrl := .customUrl -}}
{{- $showThumbnail := .showThumbnail | default false -}}
{{- $width := .width | default 600 -}}
{{- $height := .height | default 315 -}}
{{- $quality := .quality | default 85 -}}
{{- $formats := .formats | default (slice "avif" "webp" "jpg") -}}
{{- $config := dict -}}
{{- if $resource -}}
{{- if eq $type "repo" -}}
{{- if $showThumbnail -}}
{{- $config = dict
"apiUrl" (print "https://api.github.com/repos/" $resource)
"repoLink" (print "https://github.com/" $resource)
"imageUrl" (print "https://opengraph.githubassets.com/0/" $resource)
"icon" "code-bracket"
"brandColors" (slice "slate-800" "slate-900")
"typeColor" "primary-500"
"isImageEmbed" true
"imageProcessing" (dict
"width" $width
"height" $height
"quality" $quality
"formats" $formats
"sizes" (slice 400 600 800)
)
"statsConfig" (dict
"stars" (dict "icon" "star" "color" "yellow-500" "field" "stargazers_count")
"forks" (dict "icon" "git-fork" "color" "primary-500" "field" "forks_count")
"issues" (dict "icon" "exclamation-circle" "color" "red-500" "field" "open_issues_count")
)
"titleField" "name"
"descriptionField" "description"
"subtypeField" "language"
"ownerField" "owner.login"
-}}
{{- else -}}
{{- $config = dict
"apiUrl" (print "https://api.github.com/repos/" $resource)
"repoLink" (print "https://github.com/" $resource)
"icon" "code-bracket"
"brandColors" (slice "slate-800" "slate-900")
"typeColor" "primary-500"
"statsConfig" (dict
"stars" (dict "icon" "star" "color" "yellow-500" "field" "stargazers_count")
"forks" (dict "icon" "git-fork" "color" "primary-500" "field" "forks_count")
"issues" (dict "icon" "exclamation-circle" "color" "red-500" "field" "open_issues_count")
)
"titleField" "name"
"descriptionField" "description"
"subtypeField" "language"
"ownerField" "owner.login"
-}}
{{- end -}}
{{- else if eq $type "gist" -}}
{{- $config = dict
"apiUrl" (print "https://api.github.com/gists/" $resource)
"repoLink" (print "https://gist.github.com/" $resource)
"icon" "document-text"
"brandColors" (slice "slate-800" "slate-900")
"typeColor" "secondary-500"
"titleField" "description"
"descriptionField" "description"
-}}
{{- else -}}
{{- $config = dict
"repoLink" (print "https://github.com/" $resource)
"icon" "link"
"brandColors" (slice "slate-800" "slate-900")
"typeColor" "zinc-500"
-}}
{{- end -}}
{{- else if $customUrl -}}
{{- $config = dict
"repoLink" $customUrl
"icon" "link"
"brandColors" (slice "slate-800" "slate-900")
"typeColor" "zinc-500"
-}}
{{- end -}}
{{ return $config }}
@@ -0,0 +1,107 @@
{{/*
Content section rendering for embed cards
Parameters:
- customDescription: user-provided description override
- embedData: data fetched from API
- platform: platform name
- hb_id: Hugo Blox unique identifier
- config: platform configuration
- processedImage: processed image data (for image embeds)
*/}}
{{- $customDescription := .customDescription -}}
{{- $embedData := .embedData -}}
{{- $platform := .platform -}}
{{- $hb_id := .hb_id -}}
{{- $config := .config -}}
{{- $processedImage := .processedImage -}}
{{/* Display processed image if available */}}
{{- if $processedImage -}}
<div class="mb-4 overflow-hidden rounded-lg">
<img class="w-full h-auto transition-transform duration-500 ease-out group-hover:scale-105"
srcset="{{ $processedImage.srcset }}"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
src="{{ $processedImage.fallback.RelPermalink }}"
width="{{ $processedImage.fallback.Width }}"
height="{{ $processedImage.fallback.Height }}"
loading="lazy"
decoding="async"
alt="{{ if $customDescription }}{{ $customDescription }}{{ else if and $embedData $config.titleField }}{{ index $embedData $config.titleField }}{{ else }}Embedded image{{ end }}"
style="aspect-ratio: {{ $processedImage.fallback.Width }}/{{ $processedImage.fallback.Height }};">
</div>
{{- end -}}
{{/* Description handling */}}
{{- $description := $customDescription -}}
{{- if and (not $description) $embedData $config.descriptionField -}}
{{- $description = index $embedData $config.descriptionField -}}
{{/* Apply platform-specific cleanup */}}
{{- if $config.descriptionCleanup -}}
{{- $description = $description | replaceRE $config.descriptionCleanup "" -}}
{{- end -}}
{{- end -}}
{{- if $description -}}
<p class="text-zinc-600 dark:text-zinc-400 text-base leading-relaxed line-clamp-3">
{{ $description | plainify | htmlUnescape | truncate 200 | emojify }}
</p>
{{- end -}}
{{/* Platform-specific stats section */}}
{{- if and $embedData $config.statsConfig -}}
<div class="flex items-center gap-6 pt-2">
{{- range $statKey, $statConfig := $config.statsConfig -}}
{{- $statValue := index $embedData $statConfig.field -}}
{{- if $statValue -}}
<div class="flex items-center gap-1.5 text-sm text-zinc-600 dark:text-zinc-400">
{{ partial "functions/get_icon" (dict "name" $statConfig.icon "attributes" (printf "class=\"w-4 h-4 text-%s\"" $statConfig.color)) }}
{{- if and (eq $platform "github") (eq $statKey "issues") -}}
{{/* Make issues count clickable for GitHub */}}
<a href="{{ $config.repoLink }}/issues" target="_blank" rel="noopener" class="font-medium hover:text-primary-600 dark:hover:text-primary-400 hover:underline transition-colors duration-200" id="hb-{{ $hb_id }}-{{ $statKey }}">
{{- if gt $statValue 999 -}}
{{- if gt $statValue 999999 -}}
{{ div $statValue 1000000 }}M
{{- else -}}
{{ div $statValue 1000 }}k
{{- end -}}
{{- else -}}
{{ $statValue }}
{{- end -}}
</a>
{{- else -}}
<span id="hb-{{ $hb_id }}-{{ $statKey }}">
{{- if gt $statValue 999 -}}
{{- if gt $statValue 999999 -}}
{{ div $statValue 1000000 }}M
{{- else -}}
{{ div $statValue 1000 }}k
{{- end -}}
{{- else -}}
{{ $statValue }}
{{- end -}}
</span>
{{- end -}}
</div>
{{- end -}}
{{- end -}}
</div>
{{- end -}}
{{/* Additional platform-specific content */}}
{{- if eq $platform "github" -}}
{{/* Show additional GitHub-specific info if available */}}
{{- if and $embedData $embedData.topics -}}
<div class="flex flex-wrap gap-1 pt-2">
{{- range first 3 $embedData.topics -}}
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-primary-100 text-primary-800 dark:bg-primary-900/40 dark:text-primary-300">
{{ . | emojify }}
</span>
{{- end -}}
{{- if gt (len $embedData.topics) 3 -}}
<span class="text-xs text-zinc-500 dark:text-zinc-500">+{{ sub (len $embedData.topics) 3 }}</span>
{{- end -}}
</div>
{{- end -}}
{{- end -}}
@@ -0,0 +1,28 @@
{{/*
Platform icon rendering
Parameters:
- platform: platform name (huggingface, github, etc.)
- config: platform configuration dict
- hb_id: Hugo Blox unique identifier for the embed
*/}}
{{- $platform := .platform -}}
{{- $config := .config -}}
{{- $hb_id := .hb_id -}}
{{- if eq $platform "huggingface" -}}
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-{{ index $config.brandColors 0 }} to-{{ index $config.brandColors 1 }} flex items-center justify-center">
{{ partial "functions/get_icon" (dict "name" "brands/huggingface" "attributes" "class=\"w-6 h-6 text-white\"") }}
</div>
{{- else if eq $platform "github" -}}
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-{{ index $config.brandColors 0 }} to-{{ index $config.brandColors 1 }} flex items-center justify-center">
{{ partial "functions/get_icon" (dict "name" "brands/github" "attributes" "class=\"w-6 h-6 text-white\"") }}
</div>
{{- else -}}
{{/* Custom/generic embeds use neutral styling */}}
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-{{ index $config.brandColors 0 }} to-{{ index $config.brandColors 1 }} flex items-center justify-center">
{{ partial "functions/get_icon" (dict "name" ($config.icon | default "globe-alt") "attributes" "class=\"w-5 h-5 text-white\"") }}
</div>
{{- end -}}
@@ -0,0 +1,162 @@
{{/*
Title section rendering for embed cards
Parameters:
- hb_id: Hugo Blox unique identifier
- customTitle: user-provided title override
- embedData: data fetched from API
- customUrl: custom URL if provided
- resource: platform resource identifier
- type: resource type
- platform: platform name
- config: platform configuration
*/}}
{{- $hb_id := .hb_id -}}
{{- $customTitle := .customTitle -}}
{{- $embedData := .embedData -}}
{{- $customUrl := .customUrl -}}
{{- $resource := .resource -}}
{{- $type := .type -}}
{{- $platform := .platform -}}
{{- $config := .config -}}
<h3 id="hb-embed-title-{{ $hb_id }}" class="text-xl font-bold tracking-tight leading-tight truncate">
<a href="{{ $config.repoLink | default $customUrl }}" target="_blank" rel="noopener" class="text-zinc-900 dark:text-zinc-100 hover:text-primary-600 dark:hover:text-primary-400 hover:underline transition-colors duration-200">
{{- if $customTitle -}}
{{ $customTitle | emojify }}
{{- else if and $embedData $config.titleField -}}
{{ index $embedData $config.titleField | emojify }}
{{- else if and $embedData $embedData.name -}}
{{ $embedData.name | emojify }}
{{- else if and $embedData $embedData.id -}}
{{ $embedData.id | emojify }}
{{- else if $customUrl -}}
{{- $parsed := urls.Parse $customUrl -}}
{{ $parsed.Host | emojify }}
{{- else if $resource -}}
{{- if eq $platform "github" -}}
{{/* For GitHub, show just the repo name, not the full "owner/repo" */}}
{{- $parts := split $resource "/" -}}
{{- if gt (len $parts) 1 -}}
{{ index $parts 1 | emojify }}
{{- else -}}
{{ $resource | emojify }}
{{- end -}}
{{- else -}}
{{ $resource | emojify }}
{{- end -}}
{{- else -}}
Embedded Resource
{{- end -}}
</a>
</h3>
{{/* Resource type and subtype indicator */}}
{{- $showTypeIndicator := false -}}
{{- $typeText := "" -}}
{{- $typeColor := $config.typeColor | default "zinc-500" -}}
{{/* Always show type indicator for GitHub repos with data */}}
{{- if and (eq $platform "github") $embedData $config.ownerField -}}
{{- $showTypeIndicator = true -}}
{{- end -}}
{{/* Force metadata line for custom embeds to ensure proper alignment */}}
{{- if eq $platform "custom" -}}
{{- $showTypeIndicator = true -}}
{{- end -}}
{{- if $type -}}
{{- $showTypeIndicator = true -}}
{{- if and $embedData $config.subtypeField -}}
{{- if $config.subtypeIndex -}}
{{- $subtypes := index $embedData $config.subtypeField -}}
{{- if $subtypes -}}
{{- $typeText = index $subtypes $config.subtypeIndex -}}
{{- else -}}
{{- $typeText = $type -}}
{{- end -}}
{{- else -}}
{{- $typeText = index $embedData $config.subtypeField | default $type -}}
{{- end -}}
{{- else -}}
{{- $typeText = $type -}}
{{- end -}}
{{- else if and $embedData $config.subtypeField -}}
{{- $showTypeIndicator = true -}}
{{- if $config.subtypeIndex -}}
{{- $subtypes := index $embedData $config.subtypeField -}}
{{- if $subtypes -}}
{{- $typeText = index $subtypes $config.subtypeIndex -}}
{{- end -}}
{{- else -}}
{{- $typeText = index $embedData $config.subtypeField -}}
{{- end -}}
{{- end -}}
{{- if $showTypeIndicator -}}
<div class="flex items-center gap-2 mt-1">
{{/* GitHub repos: Show owner prominently, then language */}}
{{- if eq $platform "github" -}}
{{- $owner := "" -}}
{{/* Get owner from API data if available */}}
{{- if $embedData -}}
{{- if eq $config.ownerField "owner.login" -}}
{{/* Handle nested GitHub API structure: embedData.owner.login */}}
{{- $ownerObj := index $embedData "owner" -}}
{{- if $ownerObj -}}
{{- $owner = index $ownerObj "login" -}}
{{- end -}}
{{- else if $config.ownerField -}}
{{/* Handle simple field access */}}
{{- $owner = index $embedData $config.ownerField -}}
{{- end -}}
{{- end -}}
{{/* Fallback: extract owner from resource string (e.g., "HugoBlox/hugo-blox-builder" -> "HugoBlox") */}}
{{- if and (not $owner) $resource -}}
{{- $parts := split $resource "/" -}}
{{- if gt (len $parts) 0 -}}
{{- $owner = index $parts 0 -}}
{{- end -}}
{{- end -}}
{{- if $owner -}}
<span class="text-sm text-zinc-600 dark:text-zinc-400">by
<a href="https://github.com/{{ $owner }}" target="_blank" rel="noopener" class="font-medium hover:text-primary-600 dark:hover:text-primary-400 hover:underline transition-colors duration-200">{{ $owner | emojify }}</a>
</span>
{{- if $typeText -}}
<span class="text-sm text-zinc-500 dark:text-zinc-500">•</span>
<span class="inline-block w-2 h-2 rounded-full bg-{{ $typeColor }}"></span>
<span class="text-sm text-zinc-500 dark:text-zinc-500 capitalize">{{ $typeText | emojify }}</span>
{{- end -}}
{{- else if $typeText -}}
{{/* No owner, just show type */}}
<span class="inline-block w-2 h-2 rounded-full bg-{{ $typeColor }}"></span>
<span class="text-sm text-zinc-600 dark:text-zinc-400 capitalize">{{ $typeText | emojify }}</span>
{{- end -}}
{{- else if eq $platform "custom" -}}
{{/* Custom embeds: Show domain or minimal placeholder for consistent alignment */}}
{{- if $customUrl -}}
{{- $parsed := urls.Parse $customUrl -}}
{{- $domain := $parsed.Host -}}
<span class="text-sm text-zinc-500 dark:text-zinc-500">{{ $domain | emojify }}</span>
{{- else -}}
{{/* Minimal placeholder to maintain visual spacing */}}
<span class="text-sm text-zinc-500 dark:text-zinc-500 opacity-0">external resource</span>
{{- end -}}
{{- else -}}
{{/* Other platforms: Show type with indicator */}}
{{- if $typeText -}}
<span class="inline-block w-2 h-2 rounded-full bg-{{ $typeColor }}"></span>
<span class="text-sm text-zinc-600 dark:text-zinc-400 capitalize">
{{ $typeText | emojify }}
</span>
{{- else -}}
{{/* Minimal placeholder for consistent spacing */}}
<span class="text-sm text-zinc-500 dark:text-zinc-500 opacity-0">platform resource</span>
{{- end -}}
{{- end -}}
</div>
{{- end -}}
@@ -0,0 +1,67 @@
{{/*
HuggingFace platform configuration
Parameters:
- resource: model or dataset identifier
- type: "model" or "dataset"
- customUrl: optional override URL
*/}}
{{- $resource := .resource -}}
{{- $type := .type -}}
{{- $customUrl := .customUrl -}}
{{- $config := dict -}}
{{- if $resource -}}
{{- if eq $type "model" -}}
{{- $config = dict
"apiUrl" (print "https://huggingface.co/api/models/" $resource)
"repoLink" (print "https://huggingface.co/" $resource)
"icon" "cpu-chip"
"brandColors" (slice "yellow-400" "orange-500")
"typeColor" "secondary-500"
"statsConfig" (dict
"likes" (dict "icon" "heart" "color" "secondary-500" "field" "likes")
"downloads" (dict "icon" "arrow-down-tray" "color" "primary-500" "field" "downloads")
)
"titleField" "id"
"descriptionField" "description"
"descriptionCleanup" `Dataset Card for .+\s+Dataset Summary\s+`
"subtypeField" "pipeline_tag"
-}}
{{- else if eq $type "dataset" -}}
{{- $config = dict
"apiUrl" (print "https://huggingface.co/api/datasets/" $resource)
"repoLink" (print "https://huggingface.co/datasets/" $resource)
"icon" "circle-stack"
"brandColors" (slice "yellow-400" "orange-500")
"typeColor" "primary-500"
"statsConfig" (dict
"likes" (dict "icon" "heart" "color" "secondary-500" "field" "likes")
"downloads" (dict "icon" "arrow-down-tray" "color" "primary-500" "field" "downloads")
)
"titleField" "id"
"descriptionField" "description"
"descriptionCleanup" `Dataset Card for .+\s+Dataset Summary\s+`
"subtypeField" "task_categories"
"subtypeIndex" 0
-}}
{{- else -}}
{{- $config = dict
"repoLink" (print "https://huggingface.co/" $resource)
"icon" "link"
"brandColors" (slice "yellow-400" "orange-500")
"typeColor" "zinc-500"
-}}
{{- end -}}
{{- else if $customUrl -}}
{{- $config = dict
"repoLink" $customUrl
"icon" "link"
"brandColors" (slice "yellow-400" "orange-500")
"typeColor" "zinc-500"
-}}
{{- end -}}
{{ return $config }}
@@ -0,0 +1,70 @@
{{/*
Hugo Blox Builder Ecosystem Verification
Reusable verification function for Hugo Blox components.
Ensures all required Hugo Blox Builder dependencies are present.
Usage: {{ partial "functions/hbx_verify.html" . }}
Returns: "verified" or "failed"
Used by: shortcodes, blocks, advanced components
*/}}
{{/* Check for Hugo Blox specific icon system */}}
{{- $hb_icon_check := partial "functions/get_icon" (dict "name" "academic-cap" "attributes" "style=\"display: none;\"") -}}
{{/* Verify Hugo Blox data structures */}}
{{- $hb_data_check := site.Data.icons.hero -}}
{{/* Verify Hugo Blox UID generation */}}
{{- $hb_uid_check := partial "functions/uid.html" . -}}
{{/* DEBUG: Print hugo.Deps output for analysis (dev only) */}}
{{- if getenv "HUGO_BLOX_DEBUG" -}}
{{- warnf "=== DEBUG hugo.Deps output ===" -}}
{{- range $index, $dep := hugo.Deps -}}
{{- warnf "DEP %d: Path=%s, Version=%s, Vendor=%t" $index $dep.Path $dep.Version $dep.Vendor -}}
{{- end -}}
{{- warnf "=== END hugo.Deps ===" -}}
{{- end -}}
{{/* Check for required Hugo Blox module dependencies */}}
{{- $hb_module_check := false -}}
{{- $required_modules := slice "blox-tailwind" -}}
{{- range $required := $required_modules -}}
{{- range $dep := hugo.Deps -}}
{{- if strings.Contains $dep.Path $required -}}
{{/* Accept both official GitHub org paths AND local development paths */}}
{{- if or (strings.Contains $dep.Path "github.com/HugoBlox/") (strings.Contains $dep.Path "../../../modules") -}}
{{- $hb_module_check = true -}}
{{- if getenv "HUGO_BLOX_DEBUG" -}}
{{- warnf "Found Hugo Blox module: %s" $dep.Path -}}
{{- end -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Verify Hugo Blox brands icon pack */}}
{{- $hb_brands_check := site.Data.icons.brands -}}
{{/* Debug output to identify failing check (dev only) */}}
{{- if getenv "HUGO_BLOX_DEBUG" -}}
{{- warnf "=== VERIFICATION RESULTS ===" -}}
{{- warnf "Icon check: %t" (and $hb_icon_check true) -}}
{{- warnf "Data check: %t" (and $hb_data_check true) -}}
{{- warnf "UID check: %t" (and $hb_uid_check true) -}}
{{- warnf "Module check: %t" $hb_module_check -}}
{{- warnf "Brands check: %t" (and $hb_brands_check true) -}}
{{- warnf "=== END VERIFICATION ===" -}}
{{- end -}}
{{/* Set return value based on verification results */}}
{{- $return := "failed" -}}
{{- if and $hb_icon_check $hb_data_check $hb_uid_check $hb_module_check $hb_brands_check -}}
{{- $return = "verified" -}}
{{- end -}}
{{/* Return result using proper Hugo function pattern */}}
{{ return $return }}
@@ -0,0 +1,19 @@
{{/*
Hugo Blox UID Generator
Generate a unique ID for shortcodes and components.
Uses the page's unique ID combined with ordinal for uniqueness.
*/}}
{{ $uid := .Page.File.UniqueID }}
{{ $ctx := . }}
{{ range seq 16 }}
{{ with $ctx }}
{{ $uid = printf "%s-%d" $uid .Ordinal }}
{{ $ctx = .Parent }}
{{ else }}
{{ break }}
{{ end }}
{{ end }}
{{ return (crypto.MD5 $uid) }}
@@ -0,0 +1,208 @@
{{/*
Hugo Blox Embed Shortcode
Copyright (c) George Cushen
Licensed under MIT with Attribution Required:
- Copyright notice and this license must be retained
- "Powered by Hugo Blox" attribution must be maintained
- See: https://github.com/HugoBlox/hugo-blox-builder/blob/main/LICENSE.md
Docs: https://docs.hugoblox.com/content/writing-markdown-latex/
Parameters
----------
platform : default auto-detected
Platform type (huggingface, github, etc.)
resource : optional
Platform-specific resource identifier (model/dataset for HF, repo for GitHub)
type : optional
Resource type (model, dataset, repo, etc.)
title : optional
Override the default title
description : optional
Override the default description
url : optional
Direct URL to the resource
user : optional
Username/organization (for GitHub: "owner/repo")
thumbnail : default false
Show platform thumbnail (e.g., GitHub OpenGraph image)
image : optional
Remote image URL to process and display (works with any URL including Unsplash)
Image Processing Parameters (when using image parameter)
--------------------------------------------------------
width : default 800
Image width in pixels
height : default 600
Image height in pixels
quality : default 80
Image quality 1-100
formats : default ["avif", "webp", "jpg"]
Image formats to generate
Examples
--------
{{< embed platform="huggingface" resource="microsoft/DialoGPT-medium" type="model" >}}
{{< embed platform="github" resource="hugo-blox/hugo-blox-builder" type="repo" >}}
{{< embed platform="github" resource="hugo-blox/hugo-blox-builder" type="repo" thumbnail="true" >}}
{{< embed url="https://example.com" title="Custom Title" description="Description" image="https://images.unsplash.com/photo-123" >}}
{{< embed platform="github" resource="owner/repo" image="https://custom-image.jpg" width="600" height="400" >}}
*/}}
{{/* Hugo Blox Builder ecosystem verification - Required for functionality */}}
{{- $hbx_verification_result := partial "functions/hbx_verify.html" . -}}
{{- if ne $hbx_verification_result "verified" -}}
{{ errorf "Hugo Blox Embed requires complete Hugo Blox Builder theme ecosystem at %s" .Position }}
{{- end -}}
{{ $hbx_embed_id := delimit (slice "hb-embed" (partial "functions/uid.html" .)) "-" }}
{{/* New flexible parameters */}}
{{- $platform := .Get "platform" -}}
{{- $resource := .Get "resource" -}}
{{- $type := .Get "type" -}}
{{- $user := .Get "user" -}}
{{- $customTitle := .Get "title" -}}
{{- $customDescription := .Get "description" -}}
{{- $customUrl := .Get "url" -}}
{{- $imageUrl := .Get "image" -}}
{{/* Image processing parameters */}}
{{- $width := .Get "width" | default "800" | int -}}
{{- $height := .Get "height" | default "600" | int -}}
{{- $quality := .Get "quality" | default "80" | int -}}
{{- $formats := .Get "formats" | default (slice "avif" "webp" "jpg") -}}
{{- $showThumbnail := .Get "thumbnail" | default false -}}
{{/* Set default platform based on available parameters */}}
{{- if not $platform -}}
{{- if $customUrl -}}
{{- $platform = "custom" -}}
{{- else -}}
{{- $platform = "custom" -}}
{{- end -}}
{{- end -}}
{{/* Platform configuration - extensible for future platforms */}}
{{- $config := dict -}}
{{- if eq $platform "huggingface" -}}
{{- $config = partial "functions/embed/huggingface.html" (dict "resource" $resource "type" $type "customUrl" $customUrl) -}}
{{- else if eq $platform "github" -}}
{{- $config = partial "functions/embed/github.html" (dict "resource" $resource "type" $type "user" $user "customUrl" $customUrl "showThumbnail" $showThumbnail "width" $width "height" $height "quality" $quality "formats" $formats) -}}
{{- else -}}
{{/* Custom/generic embed configuration */}}
{{- $config = dict
"repoLink" $customUrl
"icon" "globe-alt"
"brandColors" (slice "zinc-700" "zinc-800")
"typeColor" "zinc-500"
-}}
{{- end -}}
{{/* Add generic image processing if image parameter is provided */}}
{{- if $imageUrl -}}
{{- $config = merge $config (dict
"imageUrl" $imageUrl
"isImageEmbed" true
"imageProcessing" (dict
"width" $width
"height" $height
"quality" $quality
"formats" $formats
"sizes" (slice 400 600 800 1200)
)
) -}}
{{- end -}}
{{/* Fetch data from API if available - with graceful fallbacks */}}
{{- $embedData := dict -}}
{{- $processedImage := dict -}}
{{- if $config.apiUrl -}}
{{- with try (resources.GetRemote $config.apiUrl) -}}
{{- with .Err -}}
{{/* Log warning but don't fail - allow graceful fallback */}}
{{- if not (strings.Contains (string .Err) "rate limit") -}}
{{- warnf "embed shortcode: failed to fetch remote resource from %q: %s (continuing with fallback display)" $config.apiUrl $.Position -}}
{{- end -}}
{{- else with .Value -}}
{{- $embedData = . | transform.Unmarshal -}}
{{- else -}}
{{/* Still warn but continue */}}
{{- warnf "embed shortcode: unable to get remote resource from %q (continuing with fallback display)" $config.apiUrl -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Process image if image URL or platform image is configured */}}
{{- if and $config.isImageEmbed $config.imageUrl -}}
{{- with try (resources.GetRemote $config.imageUrl) -}}
{{- with .Err -}}
{{- warnf "embed shortcode: failed to fetch image from %q (continuing without image): %s" $config.imageUrl $.Position -}}
{{- else with .Value -}}
{{- $remoteImg := . -}}
{{- $resizeStr := printf "%dx%d jpg q%d" $config.imageProcessing.width $config.imageProcessing.height $config.imageProcessing.quality -}}
{{- with try ($remoteImg.Resize $resizeStr) -}}
{{- with .Err -}}
{{/* Image resize failed, use original */}}
{{- $processedImage = dict "fallback" $remoteImg "srcset" $remoteImg.RelPermalink -}}
{{- else with .Value -}}
{{- $processedImage = partial "functions/process_responsive_image.html" (dict
"image" .
"mode" "responsive"
"sizes" $config.imageProcessing.sizes
"formats" $config.imageProcessing.formats
) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if or $embedData $customUrl $config.repoLink $resource $processedImage -}}
<div class="group bg-white/90 dark:bg-zinc-900/90 backdrop-blur-sm rounded-2xl ring-1 ring-zinc-900/5 dark:ring-white/10 shadow-lg overflow-hidden transition-all duration-300 ease-out hover:shadow-xl hover:shadow-primary-500/10 hover:-translate-y-1 focus-within:ring-2 focus-within:ring-primary-500/50 my-6" role="article" aria-labelledby="hb-embed-title-{{ $hbx_embed_id }}">
<!-- Header with platform branding -->
<div class="flex items-center gap-3 p-6 border-b border-zinc-100 dark:border-zinc-800">
<div class="flex-shrink-0">
{{ partial "functions/embed/hbx_platform_icon.html" (dict "platform" $platform "config" $config "hb_id" $hbx_embed_id) }}
</div>
<div class="flex-1 min-w-0">
{{ partial "functions/embed/hbx_title_section.html" (dict "hb_id" $hbx_embed_id "customTitle" $customTitle "embedData" $embedData "customUrl" $customUrl "resource" $resource "type" $type "platform" $platform "config" $config) }}
</div>
<div class="flex-shrink-0">
<a href="{{ $config.repoLink | default $customUrl }}" target="_blank" rel="noopener" class="text-zinc-400 hover:text-primary-500 transition-colors duration-200">
{{ partial "functions/get_icon" (dict "name" "arrow-top-right-on-square" "attributes" "class=\"w-5 h-5 hb-embed-link\"") }}
</a>
</div>
</div>
<!-- Content Section -->
<div class="p-6 space-y-4">
{{ partial "functions/embed/hbx_content_section.html" (dict "customDescription" $customDescription "embedData" $embedData "platform" $platform "hb_id" $hbx_embed_id "config" $config "processedImage" $processedImage) }}
</div>
<!-- Hover indicator -->
<div class="absolute inset-0 pointer-events-none bg-gradient-to-r from-primary-500/0 via-primary-500/5 to-secondary-500/0 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
<!-- Required MIT Attribution - Do Not Remove -->
<div class="sr-only" data-hb-component="embed" data-hb-version="1.0" data-hb-license="MIT">
Powered by Hugo Blox Builder - https://github.com/HugoBlox/hugo-blox-builder
</div>
</div>
{{- else -}}
{{ warnf "embed shortcode: unable to fetch data or missing required parameters: %s" .Position }}
<!-- Fallback display -->
<div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 my-6">
<div class="flex items-center gap-2 text-yellow-800 dark:text-yellow-200">
{{ partial "functions/get_icon" (dict "name" "exclamation-triangle" "attributes" "class=\"w-5 h-5\"") }}
<span class="font-medium">Embed Warning</span>
</div>
<p class="mt-1 text-sm text-yellow-700 dark:text-yellow-300">
Unable to load embedded content. Please check the parameters and try again.
</p>
</div>
{{- end -}}
@@ -1,6 +1,6 @@
---
title: 📈 Communicate your results effectively with the best data visualizations
summary: Use popular tools such as Plotly, Mermaid, and data frames.
summary: Use popular tools such as HuggingFace, Plotly, Mermaid, and data frames.
date: 2023-10-25
authors:
- admin
@@ -16,6 +16,34 @@ Hugo Blox is designed to give technical content creators a seamless experience.
Use popular tools such as Plotly, Mermaid, and data frames.
## Embed Rich Content
HuggingFace Model
{{< embed platform="huggingface" resource="google/embeddinggemma-300m" type="model" >}}
HuggingFace Dataset
{{< embed platform="huggingface" resource="fka/awesome-chatgpt-prompts" type="dataset" >}}
GitHub Repository
{{< embed platform="github" resource="HugoBlox/hugo-blox-builder" type="repo" >}}
Custom embed with manual data
{{< embed url="https://example.com" title="My Custom Resource" description="A great resource for learning" >}}
### Custom Images
Embed beautiful images from any source with Hugo image processing (Unsplash, custom URLs, etc.):
{{< embed url="https://example.com" title="Data Visualization Guide" description="Beautiful data visualization workspace" image="https://images.unsplash.com/photo-1514888286974-6c03e2ca1dba?q=80&w=800&h=600&auto=format&fit=crop" width="800" height="600" quality="90" >}}
You can also add images to any platform embed:
{{< embed platform="github" resource="plotly/plotly.py" type="repo" image="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=600&h=400&auto=format&fit=crop" width="600" height="400" >}}
## Charts
Hugo Blox supports the popular [Plotly](https://plot.ly/) format for interactive data visualizations. With Plotly, you can design almost any kind of visualization you can imagine!
@@ -154,4 +182,56 @@ renders as
{{< table path="results.csv" header="true" caption="Table 1: My results" >}}
## Interactive Buttons
Add engaging call-to-action buttons to your data visualization posts:
### Basic Buttons
{{< button url="/" >}}Contact Us{{< /button >}}
&nbsp;
{{< button url="https://plotly.com/python/" new_tab="true" style="secondary" >}}Learn Plotly{{< /button >}}
```go-html-template
{{</* button url="/" */>}}Contact Us{{</* /button */>}}
{{</* button url="https://plotly.com/python/" new_tab="true" style="secondary" */>}}Learn Plotly{{</* /button */>}}
```
### Styled Buttons for Data Actions
{{< button url="#" style="primary" size="lg" align="center" icon="chart-bar" >}}View Dashboard{{< /button >}}
&nbsp;
{{< button url="/data/results.csv" style="outline" icon="document-arrow-down" >}}Download Data{{< /button >}}
&nbsp;
{{< button url="https://github.com/HugoBlox" new_tab="true" style="ghost" icon="arrow-top-right-on-square" icon_position="right" >}}View Source Code{{< /button >}}
```go-html-template
{{</* button url="#" style="primary" size="lg" align="center" icon="chart-bar" */>}}View Dashboard{{</* /button */>}}
{{</* button url="/data/results.csv" style="outline" icon="document-arrow-down" */>}}Download Data{{</* /button */>}}
{{</* button url="https://github.com/HugoBlox" new_tab="true" style="ghost" icon="arrow-top-right-on-square" icon_position="right" */>}}View Source Code{{</* /button */>}}
```
### Multiple Aligned Buttons
{{< button url="https://jupyter.org/" new_tab="true" style="secondary" rounded="full" align="center" >}}Try Jupyter{{< /button >}}
&nbsp;
{{< button url="https://colab.research.google.com/" new_tab="true" style="primary" rounded="full" align="center" icon="rocket-launch" >}}Open in Colab{{< /button >}}
```go-html-template
{{</* button url="https://jupyter.org/" new_tab="true" style="secondary" rounded="full" align="center" */>}}Try Jupyter{{</* /button */>}}
{{</* button url="https://colab.research.google.com/" new_tab="true" style="primary" rounded="full" align="center" icon="rocket-launch" */>}}Open in Colab{{</* /button */>}}
```
## Did you find this page helpful? Consider sharing it 🙌
@@ -18,9 +18,6 @@ tags:
- Markdown
content_meta:
# content_type: 'Tutorial'
# difficulty: 'Beginner'
prerequisites: ['Markdown']
trending: true
---
@@ -8,6 +8,11 @@ tags:
- JavaScript
image:
caption: 'Embed rich media such as videos and LaTeX math'
content_meta:
content_type: 'Tutorial'
difficulty: 'Beginner'
prerequisites: ['HTML']
trending: true
---
[Hugo Blox Builder](https://hugoblox.com) is designed to give technical content creators a seamless experience. You can focus on the content and the Hugo Blox Builder which this template is built upon handles the rest.
@@ -112,7 +117,6 @@ $$
Hugo Blox Builder utilises Hugo's Markdown extension for highlighting code syntax. The code theme can be selected in the `config/_default/params.yaml` file.
```python
import pandas as pd
data = pd.read_csv("data.csv")
@@ -8,6 +8,11 @@ tags:
- Python
image:
caption: 'Embed rich media such as videos and LaTeX math'
content_meta:
content_type: 'Course'
difficulty: 'Intermediate'
prerequisites: ['SQL']
trending: false
---
[Hugo Blox Builder](https://hugoblox.com) is designed to give technical content creators a seamless experience. You can focus on the content and the Hugo Blox Builder which this template is built upon handles the rest.
@@ -112,7 +117,6 @@ $$
Hugo Blox Builder utilises Hugo's Markdown extension for highlighting code syntax. The code theme can be selected in the `config/_default/params.yaml` file.
```python
import pandas as pd
data = pd.read_csv("data.csv")
@@ -5,6 +5,7 @@ title: Shortcodes
Build the best docs with re-usable components, referred to as Hugo shortcodes:
{{< cards >}}
{{< card url="button" title="Button" icon="cursor-arrow-rays" >}}
{{< card url="callout" title="Callout" icon="warning" >}}
{{< card url="cards" title="Cards" icon="card" >}}
{{< card url="toggle" title="Spoiler" icon="chevron-right" >}}
@@ -0,0 +1,202 @@
---
title: Button Shortcode
linkTitle: Button
---
A modern, customizable button shortcode with gradient styling, icons, and smart link handling.
<!--more-->
## Basic Usage
{{< button url="/contact" >}}Contact Us{{< /button >}}
{{< button url="https://example.com" new_tab="true" style="secondary" >}}Visit External Site{{< /button >}}
The above buttons are created with:
```go-html-template
{{</* button url="/contact" */>}}Contact Us{{</* /button */>}}
{{</* button url="https://example.com" new_tab="true" style="secondary" */>}}Visit External Site{{</* /button */>}}
```
## Style Variants
### Primary (Default)
{{< button url="#" style="primary" >}}Primary Button{{< /button >}}
```go-html-template
{{</* button url="#" style="primary" */>}}Primary Button{{</* /button */>}}
```
### Secondary
{{< button url="#" style="secondary" >}}Secondary Button{{< /button >}}
```go-html-template
{{</* button url="#" style="secondary" */>}}Secondary Button{{</* /button */>}}
```
### Outline
{{< button url="#" style="outline" >}}Outline Button{{< /button >}}
```go-html-template
{{</* button url="#" style="outline" */>}}Outline Button{{</* /button */>}}
```
### Ghost
{{< button url="#" style="ghost" >}}Ghost Button{{< /button >}}
```go-html-template
{{</* button url="#" style="ghost" */>}}Ghost Button{{</* /button */>}}
```
## Sizes
### Small
{{< button url="#" size="sm" >}}Small Button{{< /button >}}
### Medium (Default)
{{< button url="#" size="md" >}}Medium Button{{< /button >}}
### Large
{{< button url="#" size="lg" >}}Large Button{{< /button >}}
### Extra Large
{{< button url="#" size="xl" >}}Extra Large{{< /button >}}
```go-html-template
{{</* button url="#" size="sm" */>}}Small Button{{</* /button */>}}
{{</* button url="#" size="md" */>}}Medium Button{{</* /button */>}}
{{</* button url="#" size="lg" */>}}Large Button{{</* /button */>}}
{{</* button url="#" size="xl" */>}}Extra Large{{</* /button */>}}
```
## Alignment
### Left (Default)
{{< button url="#" align="left" >}}Left Aligned{{< /button >}}
### Center
{{< button url="#" align="center" >}}Center Aligned{{< /button >}}
### Right
{{< button url="#" align="right" >}}Right Aligned{{< /button >}}
```go-html-template
{{</* button url="#" align="left" */>}}Left Aligned{{</* /button */>}}
{{</* button url="#" align="center" */>}}Center Aligned{{</* /button */>}}
{{</* button url="#" align="right" */>}}Right Aligned{{</* /button */>}}
```
## With Icons
### Icon Before Text
{{< button url="#" icon="download" >}}Download{{< /button >}}
### Icon After Text
{{< button url="#" icon="arrow-right" icon_position="right" >}}Continue{{< /button >}}
```go-html-template
{{</* button url="#" icon="download" */>}}Download{{</* /button */>}}
{{</* button url="#" icon="arrow-right" icon_position="right" */>}}Continue{{</* /button */>}}
```
## Rounded Corners
### Small Radius
{{< button url="#" rounded="sm" >}}Small Radius{{< /button >}}
### Medium Radius (Default)
{{< button url="#" rounded="md" >}}Medium Radius{{< /button >}}
### Large Radius
{{< button url="#" rounded="lg" >}}Large Radius{{< /button >}}
### Pill Shape
{{< button url="#" rounded="full" >}}Pill Button{{< /button >}}
```go-html-template
{{</* button url="#" rounded="sm" */>}}Small Radius{{</* /button */>}}
{{</* button url="#" rounded="md" */>}}Medium Radius{{</* /button */>}}
{{</* button url="#" rounded="lg" */>}}Large Radius{{</* /button */>}}
{{</* button url="#" rounded="full" */>}}Pill Button{{</* /button */>}}
```
## Advanced Examples
### Call-to-Action Button
{{< button url="/signup" style="primary" size="lg" align="center" icon="rocket-launch" >}}Get Started Today{{< /button >}}
```go-html-template
{{</* button url="/signup" style="primary" size="lg" align="center" icon="rocket-launch" */>}}Get Started Today{{</* /button */>}}
```
### External Link with New Tab
{{< button url="https://github.com/hugo-blox/hugo-blox-builder" new_tab="true" style="outline" icon="arrow-top-right-on-square" icon_position="right" >}}View on GitHub{{< /button >}}
```go-html-template
{{</* button url="https://github.com/hugo-blox/hugo-blox-builder" new_tab="true" style="outline" icon="arrow-top-right-on-square" icon_position="right" */>}}View on GitHub{{</* /button */>}}
```
### Download Button
{{< button url="/files/document.pdf" style="secondary" icon="document-arrow-down" rounded="full" >}}Download PDF{{< /button >}}
```go-html-template
{{</* button url="/files/document.pdf" style="secondary" icon="document-arrow-down" rounded="full" */>}}Download PDF{{</* /button */>}}
```
## Parameters
| Parameter | Type | Default | Description |
| --------------- | ------- | ------------- | ----------------------------------------------------------- |
| `url` | string | `#` | **Required.** Button destination URL (internal or external) |
| `text` | string | Inner content | Button text (overrides shortcode content) |
| `new_tab` | boolean | `false` | Whether to open link in new tab |
| `style` | string | `primary` | Button style: `primary`, `secondary`, `outline`, `ghost` |
| `size` | string | `md` | Button size: `sm`, `md`, `lg`, `xl` |
| `align` | string | `left` | Button alignment: `left`, `center`, `right` |
| `icon` | string | - | Icon name from [Hero Icons](https://heroicons.com/) |
| `icon_position` | string | `left` | Icon position: `left`, `right` |
| `rounded` | string | `md` | Border radius: `sm`, `md`, `lg`, `xl`, `full` |
| `disabled` | boolean | `false` | Whether button should be disabled |
## Security Features
The button shortcode automatically handles security for external links:
- **External links** get `rel="noreferrer"` attribute
- **External links opening in new tab** get `rel="noopener noreferrer"`
- **Internal links opening in new tab** get `rel="noopener"`
This ensures safe navigation while maintaining functionality.
## Accessibility
The button shortcode includes built-in accessibility features:
- Proper `role="button"` attribute
- `aria-label` support
- Keyboard focus indicators
- High contrast focus rings
- Disabled state handling