eleventy.config.mjs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. import { readFileSync } from 'node:fs';
  2. import { EleventyRenderPlugin } from "@11ty/eleventy";
  3. import { join, dirname } from 'node:path';
  4. import { sync } from 'glob';
  5. /*
  6. * Copy list
  7. */
  8. const getCopyList = () => {
  9. let copy = {
  10. "node_modules/@tabler/core/dist": "dist",
  11. "pages/favicon.ico": "favicon.ico",
  12. "static": "static",
  13. }
  14. const libs = JSON.parse(readFileSync('./pages/_data/libs.json'));
  15. let files = []
  16. Object.keys(libs.js).forEach((lib) => {
  17. files.push(Array.isArray(libs.js[lib]) ? libs.js[lib] : [libs.js[lib]])
  18. })
  19. Object.keys(libs.css).forEach((lib) => {
  20. files.push(Array.isArray(libs.css[lib]) ? libs.css[lib] : [libs.css[lib]])
  21. })
  22. Object.keys(libs['js-copy']).forEach((lib) => {
  23. files.push(libs['js-copy'][lib])
  24. })
  25. files = files.flat()
  26. files.forEach((file) => {
  27. if (!file.match(/^https?/)) {
  28. copy[`node_modules/${dirname(file)}`] = `libs/${dirname(file) }`;
  29. }
  30. })
  31. return copy;
  32. }
  33. /** @type {import('@11ty/eleventy').LocalConfig} */
  34. export default function (eleventyConfig) {
  35. const environment = process.env.NODE_ENV || "production";
  36. eleventyConfig.setInputDirectory("pages");
  37. eleventyConfig.setOutputDirectory("dist");
  38. eleventyConfig.setLayoutsDirectory("_layouts");
  39. eleventyConfig.setIncludesDirectory("_includes");
  40. // eleventyConfig.addWatchTarget("../core/dist/**");
  41. // eleventyConfig.setWatchThrottleWaitTime(100);
  42. eleventyConfig.addPassthroughCopy(getCopyList());
  43. eleventyConfig.setServerPassthroughCopyBehavior("passthrough");
  44. eleventyConfig.addPlugin(EleventyRenderPlugin, {
  45. accessGlobalData: true,
  46. });
  47. eleventyConfig.setLiquidOptions({
  48. timezoneOffset: 0,
  49. jekyllInclude: true,
  50. dynamicPartials: true,
  51. jekyllWhere: true,
  52. });
  53. /**
  54. * Server
  55. */
  56. if (process.env.ELEVENTY_RUN_MODE === "serve") {
  57. eleventyConfig.setServerPassthroughCopyBehavior("passthrough");
  58. }
  59. /**
  60. * Data
  61. */
  62. eleventyConfig.addGlobalData("environment", environment);
  63. eleventyConfig.addGlobalData("package", JSON.parse(readFileSync(join("..", "core", "package.json"), "utf-8")));
  64. eleventyConfig.addGlobalData("readme", readFileSync(join("..", "README.md"), "utf-8"));
  65. eleventyConfig.addGlobalData("license", readFileSync(join("..", "LICENSE"), "utf-8"));
  66. eleventyConfig.addGlobalData("changelog", readFileSync(join("..", "CHANGELOG.md"), "utf-8"));
  67. eleventyConfig.addGlobalData("pages", () => {
  68. return sync('pages/**/*.html').filter((file) => {
  69. return !file.includes('pages/_') && !file.includes('pages/docs/index.html');
  70. }).map((file) => {
  71. return {
  72. url: file.replace(/^pages\//, '/')
  73. }
  74. });
  75. });
  76. eleventyConfig.addGlobalData("site", {
  77. title: "Tabler",
  78. description: "Premium and Open Source dashboard template with responsive and high quality UI.",
  79. themeColor: "#066fd1",
  80. email: "support@tabler.io",
  81. homepage: "https://tabler.io",
  82. githubUrl: "https://github.com/tabler/tabler",
  83. githubSponsorsUrl: "https://github.com/sponsors/codecalm",
  84. changelogUrl: "https://github.com/tabler/tabler/releases",
  85. sponsorUrl: "https://github.com/sponsors/codecalm",
  86. previewUrl: "https://preview.tabler.io",
  87. docsUrl: "https://tabler.io/docs",
  88. mapboxKey: "pk.eyJ1IjoidGFibGVyIiwiYSI6ImNscHh3dnhndjB2M3QycW85bGd0NXRmZ3YifQ.9LfHPsNoEXQH-xzz-81Ffw",
  89. googleMapsKey: "AIzaSyAr5mRB4U1KRkVznIrDWEvZjroYcD202DI",
  90. googleMapsDevKey: "AIzaSyCL-BY8-sq12m0S9H-S_yMqDmcun3A9znw",
  91. npmPackage: "@tabler/core",
  92. tablerCssPlugins: [
  93. "tabler-flags",
  94. "tabler-socials",
  95. "tabler-payments",
  96. "tabler-vendors",
  97. "tabler-marketing"
  98. ],
  99. icons: {
  100. link: "https://tabler.io/icons"
  101. },
  102. emails: {
  103. price: "$29",
  104. buy_link: "https://r.tabler.io/buy-emails"
  105. },
  106. illustrations: {
  107. price: "$59",
  108. count: 50,
  109. buy_link: "https://r.tabler.io/buy-illustrations"
  110. },
  111. colors: {
  112. "blue": {
  113. "class": "blue",
  114. "hex": "#066fd1",
  115. "title": "Blue"
  116. },
  117. "azure": {
  118. "class": "azure",
  119. "hex": "#45aaf2",
  120. "title": "Azure"
  121. },
  122. "indigo": {
  123. "class": "indigo",
  124. "hex": "#6574cd",
  125. "title": "Indigo"
  126. },
  127. "purple": {
  128. "class": "purple",
  129. "hex": "#a55eea",
  130. "title": "Purple"
  131. },
  132. "pink": {
  133. "class": "pink",
  134. "hex": "#f66d9b",
  135. "title": "Pink"
  136. },
  137. "red": {
  138. "class": "red",
  139. "hex": "#fa4654",
  140. "title": "Red"
  141. },
  142. "orange": {
  143. "class": "orange",
  144. "hex": "#fd9644",
  145. "title": "Orange"
  146. },
  147. "yellow": {
  148. "class": "yellow",
  149. "hex": "#f1c40f",
  150. "title": "Yellow"
  151. },
  152. "lime": {
  153. "class": "lime",
  154. "hex": "#7bd235",
  155. "title": "Lime"
  156. },
  157. "green": {
  158. "class": "green",
  159. "hex": "#5eba00",
  160. "title": "Green"
  161. },
  162. "teal": {
  163. "class": "teal",
  164. "hex": "#2bcbba",
  165. "title": "Teal"
  166. },
  167. "cyan": {
  168. "class": "cyan",
  169. "hex": "#17a2b8",
  170. "title": "Cyan"
  171. }
  172. },
  173. skinColors: {
  174. "rose": {
  175. "hex": "#FFCB9D",
  176. "title": "Rose",
  177. "class": "rose"
  178. },
  179. "yellow": {
  180. "hex": "#F0BA60",
  181. "title": "Yellow",
  182. "class": "yellow"
  183. },
  184. "skin-1": {
  185. "hex": "#e2c6a7",
  186. "title": "Skin 1",
  187. "class": "skin-1"
  188. },
  189. "skin-2": {
  190. "hex": "#c7a786",
  191. "title": "Skin 2",
  192. "class": "skin-2"
  193. },
  194. "skin-3": {
  195. "hex": "#a68063",
  196. "title": "Skin 3",
  197. "class": "skin-3"
  198. },
  199. "skin-4": {
  200. "hex": "#926241",
  201. "title": "Skin 4",
  202. "class": "skin-4"
  203. },
  204. "skin-5": {
  205. "hex": "#654c45",
  206. "title": "Skin 5",
  207. "class": "skin-5"
  208. },
  209. "gray": {
  210. "hex": "#d5d7dd",
  211. "title": "Gray",
  212. "class": "gray"
  213. }
  214. },
  215. colorsExtra: {
  216. "white": {
  217. "hex": "#ffffff",
  218. "title": "White"
  219. },
  220. "dark": {
  221. "hex": "#303645",
  222. "title": "Dark"
  223. },
  224. "gray": {
  225. "hex": "#868e96",
  226. "title": "Gray"
  227. }
  228. },
  229. variants: [
  230. {
  231. "name": "success",
  232. "icon": "check"
  233. },
  234. {
  235. "name": "info",
  236. "icon": "info-circle"
  237. },
  238. {
  239. "name": "warning",
  240. "icon": "alert-triangle"
  241. },
  242. {
  243. "name": "danger",
  244. "icon": "alert-circle"
  245. }
  246. ],
  247. "themeColors": {
  248. "primary": {
  249. "class": "primary",
  250. "title": "Primary"
  251. },
  252. "secondary": {
  253. "class": "secondary",
  254. "title": "Secondary"
  255. },
  256. "success": {
  257. "class": "success",
  258. "title": "Success"
  259. },
  260. "warning": {
  261. "class": "warning",
  262. "title": "Warning"
  263. },
  264. "danger": {
  265. "class": "danger",
  266. "title": "Danger"
  267. },
  268. "info": {
  269. "class": "info",
  270. "title": "Info"
  271. },
  272. "dark": {
  273. "class": "dark",
  274. "title": "Dark"
  275. },
  276. "light": {
  277. "class": "light",
  278. "title": "Light"
  279. }
  280. },
  281. "buttonStates": [
  282. {
  283. "class": null,
  284. "title": "Normal"
  285. },
  286. {
  287. "class": "active",
  288. "title": "Active state"
  289. },
  290. {
  291. "class": "disabled",
  292. "title": "Disabled"
  293. }
  294. ],
  295. "socials": {
  296. "x": {
  297. "icon": "brand-x",
  298. "title": "X"
  299. },
  300. "facebook": {
  301. "icon": "brand-facebook",
  302. "title": "Facebook"
  303. },
  304. "twitter": {
  305. "icon": "brand-twitter",
  306. "title": "Twitter"
  307. },
  308. "google": {
  309. "icon": "brand-google",
  310. "title": "Google"
  311. },
  312. "youtube": {
  313. "icon": "brand-youtube",
  314. "title": "Youtube"
  315. },
  316. "vimeo": {
  317. "icon": "brand-vimeo",
  318. "title": "Vimeo"
  319. },
  320. "dribbble": {
  321. "icon": "brand-dribbble",
  322. "title": "Dribbble"
  323. },
  324. "github": {
  325. "icon": "brand-github",
  326. "title": "Github"
  327. },
  328. "instagram": {
  329. "icon": "brand-instagram",
  330. "title": "Instagram"
  331. },
  332. "pinterest": {
  333. "icon": "brand-pinterest",
  334. "title": "Pinterest"
  335. },
  336. "vk": {
  337. "icon": "brand-vk",
  338. "title": "VK"
  339. },
  340. "rss": {
  341. "icon": "rss",
  342. "title": "RSS"
  343. },
  344. "flickr": {
  345. "icon": "brand-flickr",
  346. "title": "Flickr"
  347. },
  348. "bitbucket": {
  349. "icon": "brand-bitbucket",
  350. "title": "Bitbucket"
  351. },
  352. "tabler": {
  353. "icon": "brand-tabler",
  354. "title": "Tabler"
  355. }
  356. },
  357. "months-short": [
  358. "Jan",
  359. "Feb",
  360. "Mar",
  361. "Apr",
  362. "May",
  363. "Jun",
  364. "Jul",
  365. "Aug",
  366. "Sep",
  367. "Oct",
  368. "Nov",
  369. "Dec"
  370. ],
  371. "months-long": [
  372. "January",
  373. "February",
  374. "March",
  375. "April",
  376. "May",
  377. "June",
  378. "July",
  379. "August",
  380. "September",
  381. "October",
  382. "November",
  383. "December"
  384. ]
  385. });
  386. eleventyConfig.addGlobalData("sri", {
  387. "css-flags-rtl-hash": "sha384-pyPIUUzl3ihMh/Soc0cX/ytLylBiU0K+g8EWmeDVnLR6QkrAsHcOGehOffLG19t5",
  388. "css-marketing-hash": "sha384-xtswiyYvkn30pwQanIC7fLNoXLUTPJoo0/VevYIWw2PHUXjVyhibnid19Bzo4fnP",
  389. "css-flags-hash": "sha384-pyPIUUzl3ihMh/Soc0cX/ytLylBiU0K+g8EWmeDVnLR6QkrAsHcOGehOffLG19t5",
  390. "css-payments-rtl-hash": "sha384-cp6pMaF85f8bRADXNb55+643IaU3eVkxCcvTcUPzV56C24zq1pFSK/SNDfOZ1XNr",
  391. "css-socials-hash": "sha384-RNz6i9B2zB8bLNfdG34OmayEIvSFYCPovYYZebkDJf6l6drBVfm9FPmoWHasyaUz",
  392. "css-marketing-rtl-hash": "sha384-dSeYfYFDOz00AUT2Po+SELUDHixM+Qv2whYHtJtH0SC3dQL0DFaHVqXuW6unncv+",
  393. "css-payments-hash": "sha384-cp6pMaF85f8bRADXNb55+643IaU3eVkxCcvTcUPzV56C24zq1pFSK/SNDfOZ1XNr",
  394. "css-socials-rtl-hash": "sha384-RNz6i9B2zB8bLNfdG34OmayEIvSFYCPovYYZebkDJf6l6drBVfm9FPmoWHasyaUz",
  395. "css-rtl-hash": "sha384-xJaddD8d0lNiF2lmKxub9uWOGHpUMcHJzw/F5g7ikM8rPHLj9IWH1MwSibuSJAX+",
  396. "css-hash": "sha384-anrzUYCd0msxXiEJRrb2PDJRk070WI/z1nRWndATF3ls2sIWSHMI6l/grX625viM",
  397. "css-vendors-rtl-hash": "sha384-5wy2rI8a18XT4g7Zn/riZg0kPUGQm3EzGhlaPcne8YvwmiMR++ns+XtlO3ZPmyBp",
  398. "css-vendors-hash": "sha384-vCMaMQTQttXNVZtTZHpgrXqajb77YHPmldMvC680DBW5rf8wemoJyhjMCSFMb5hC",
  399. "js-hash": "sha384-gQY8IHXmWA4xT6ygJrbdFeIGkA4DytGYMKMdcNucY8IuB2BLqpW68jw9pcx0Ls4E",
  400. });
  401. /**
  402. * Filters
  403. */
  404. eleventyConfig.addFilter("miliseconds_to_minutes", function (value) {
  405. // Raturn 3:45 time format
  406. const minutes = Math.floor(value / 60000);
  407. const seconds = ((value % 60000) / 1000).toFixed(0);
  408. return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
  409. });
  410. eleventyConfig.addFilter("relative", (page) => {
  411. const segments = (page.url || '').replace(/^\//).split('/');
  412. if (segments.length === 1) {
  413. return '.';
  414. } else {
  415. return '../'.repeat(segments.length - 1).slice(0, -1);
  416. }
  417. });
  418. eleventyConfig.addFilter("contains", (items, item) => {
  419. return items && Array.isArray(items) && items.includes(item);
  420. });
  421. eleventyConfig.addFilter("concat_objects", function (object, object2) {
  422. if (
  423. object &&
  424. object2 &&
  425. typeof object === 'object' &&
  426. typeof object2 === 'object' &&
  427. !Array.isArray(object) &&
  428. !Array.isArray(object2)
  429. ) {
  430. return { ...object, ...object2 };
  431. }
  432. return object;
  433. });
  434. eleventyConfig.addFilter("replace_regex", function (input, regStr, replStr) {
  435. const regex = new RegExp(regStr, 'gm');
  436. return input.replace(regex, replStr);
  437. });
  438. eleventyConfig.addFilter("timestamp_to_date", function (timestamp) {
  439. const date = new Date(timestamp * 1000); // Convert timestamp to milliseconds
  440. return date.toISOString().split('T')[0]; // Extract the date in 'YYYY-MM-DD' format
  441. });
  442. eleventyConfig.addFilter("split_to_n", function (arr, n) {
  443. const chunkSize = Math.round(arr.length / n);
  444. const result = [];
  445. for (let i = 0; i < arr.length; i += chunkSize) {
  446. result.push(arr.slice(i, i + chunkSize));
  447. }
  448. return result;
  449. })
  450. eleventyConfig.addFilter("format_number", function (value) {
  451. return value.toString()
  452. .split('')
  453. .reverse()
  454. .reduce((acc, char, index) => {
  455. if (index > 0 && index % 3 === 0) {
  456. acc.push(',');
  457. }
  458. acc.push(char);
  459. return acc;
  460. }, [])
  461. .reverse()
  462. .join('');
  463. });
  464. function randomNumber(x, min = 0, max = 100, round = 0) {
  465. let value = ((x * x * Math.PI * Math.E * (max + 1) * (Math.sin(x) / Math.cos(x * x))) % (max + 1 - min)) + min;
  466. value = value > max ? max : value;
  467. value = value < min ? min : value;
  468. if (round !== 0) {
  469. value = parseFloat(value.toFixed(round));
  470. } else {
  471. value = Math.floor(value);
  472. }
  473. return value;
  474. }
  475. eleventyConfig.addFilter("random_date_ago", function (x, daysAgo = 100) {
  476. const today = new Date();
  477. const randomDaysAgo = randomNumber(x, 0, daysAgo);
  478. today.setDate(today.getDate() - randomDaysAgo);
  479. return today;
  480. });
  481. eleventyConfig.addFilter("random_date", function (x, startDate = null, endDate = null) {
  482. const start = startDate ? new Date(startDate).getTime() : Date.now() - 100 * 24 * 60 * 60 * 1000;
  483. const end = endDate ? new Date(endDate).getTime() : Date.now();
  484. const randomTimestamp = randomNumber(x, start, end);
  485. return new Date(randomTimestamp);
  486. });
  487. eleventyConfig.addFilter("random_item", function (x, items) {
  488. const index = randomNumber(x, 0, items.length - 1);
  489. return items[index];
  490. });
  491. eleventyConfig.addFilter("random_number", randomNumber);
  492. eleventyConfig.addFilter("first_letters", function capitalizeFirstLetter(string) {
  493. return string.split(' ').map(word => word.charAt(0)).join('');
  494. })
  495. eleventyConfig.addFilter("size", function (elem) {
  496. if (elem instanceof Object) {
  497. return Object.keys(elem).length;
  498. }
  499. return elem.length;
  500. })
  501. eleventyConfig.addFilter("first", function (elem) {
  502. if (elem instanceof Object) {
  503. return elem[Object.keys(elem)[0]];
  504. }
  505. return elem[0];
  506. })
  507. // time ago from today
  508. eleventyConfig.addFilter("timeago", function (date) {
  509. const seconds = Math.floor((new Date() - date) / 1000);
  510. let interval = Math.floor(seconds / 31536000);
  511. if (interval > 1) {
  512. return interval + " years ago";
  513. }
  514. interval = Math.floor(seconds / 2592000);
  515. if (interval > 1) {
  516. return interval + " months ago";
  517. }
  518. interval = Math.floor(seconds / 86400);
  519. if (interval > 1) {
  520. return interval + " days ago";
  521. }
  522. interval = Math.floor(seconds / 3600);
  523. if (interval > 1) {
  524. return interval + " hours ago";
  525. }
  526. interval = Math.floor(seconds / 60);
  527. if (interval > 1) {
  528. return interval + " minutes ago";
  529. }
  530. if (seconds > 0) {
  531. return Math.floor(seconds) + " seconds ago";
  532. }
  533. return "now";
  534. })
  535. /**
  536. * Shortcodes
  537. */
  538. const tags = ["capture_global", "endcapture_global", "highlight", "endhighlight"];
  539. tags.forEach(tag => {
  540. eleventyConfig.addLiquidTag(tag, function (liquidEngine) {
  541. return {
  542. parse: function (tagToken, remainingTokens) {
  543. this.str = tagToken.args;
  544. },
  545. render: function (scope, hash) {
  546. return "";
  547. },
  548. };
  549. });
  550. });
  551. /**
  552. * Transforms
  553. */
  554. function prettifyHTML(content, outputPath) {
  555. return outputPath.endsWith('.html')
  556. ? content
  557. .replace(/\/\/ @formatter:(on|off)\n+/gm, '')
  558. // remove empty lines
  559. .replace(/^\s*[\r\n]/gm, '')
  560. : content
  561. }
  562. eleventyConfig.addTransform('htmlformat', prettifyHTML)
  563. };