From d958a29862d6ea13c41fa18113b85b8cce43e12a Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Tue, 27 Feb 2024 00:55:38 +0000 Subject: [PATCH] Add author page --- pnpm-lock.yaml | 125 +++++++----------- src/components/GuideHeader.astro | 42 +++--- src/components/GuideListItem.astro | 24 ++-- src/data/authors/fernando.md | 11 ++ src/data/authors/kamran.md | 13 ++ src/data/guides/asymptotic-notation.md | 5 +- ...er-blocking-javascript-with-async-defer.md | 5 +- src/data/guides/backend-languages.md | 38 ++---- src/data/guides/basic-authentication.md | 5 +- src/data/guides/basics-of-authentication.md | 5 +- src/data/guides/big-o-notation.md | 5 +- src/data/guides/character-encodings.md | 5 +- src/data/guides/ci-cd.md | 5 +- ...istency-patterns-in-distributed-systems.md | 5 +- src/data/guides/design-patterns-for-humans.md | 5 +- src/data/guides/dhcp-in-one-picture.md | 5 +- src/data/guides/dns-in-one-picture.md | 5 +- .../guides/free-resources-to-learn-llms.md | 5 +- src/data/guides/history-of-javascript.md | 5 +- src/data/guides/how-to-setup-a-jump-server.md | 5 +- src/data/guides/http-basic-authentication.md | 5 +- src/data/guides/http-caching.md | 5 +- src/data/guides/introduction-to-llms.md | 5 +- src/data/guides/journey-to-http2.md | 5 +- src/data/guides/jwt-authentication.md | 5 +- src/data/guides/levels-of-seniority.md | 5 +- src/data/guides/oauth.md | 5 +- src/data/guides/random-numbers.md | 5 +- src/data/guides/scaling-databases.md | 5 +- src/data/guides/session-authentication.md | 5 +- .../guides/session-based-authentication.md | 5 +- .../setup-and-auto-renew-ssl-certificates.md | 5 +- .../guides/single-command-database-setup.md | 5 +- src/data/guides/ssl-tls-https-ssh.md | 5 +- src/data/guides/sso.md | 5 +- src/data/guides/token-authentication.md | 5 +- src/data/guides/unfamiliar-codebase.md | 5 +- src/data/guides/what-are-web-vitals.md | 5 +- src/data/guides/what-is-internet.md | 5 +- src/data/guides/what-is-sli-slo-sla.md | 5 +- src/env.d.ts | 1 - src/icons/github.svg | 2 +- src/icons/globe.svg | 1 + src/icons/linkedin-2.svg | 10 ++ src/lib/author.ts | 73 ++++++++++ src/lib/guide.ts | 32 +++-- src/lib/roadmap.ts | 14 +- src/lib/video.ts | 15 +-- src/pages/authors/[authorId].astro | 110 +++++++++++++++ 49 files changed, 381 insertions(+), 300 deletions(-) create mode 100644 src/data/authors/fernando.md create mode 100644 src/data/authors/kamran.md create mode 100644 src/icons/globe.svg create mode 100644 src/icons/linkedin-2.svg create mode 100644 src/lib/author.ts create mode 100644 src/pages/authors/[authorId].astro diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f5dd0b464..b7831ce0e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,7 @@ settings: dependencies: '@astrojs/react': specifier: ^3.0.10 - version: 3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0)(vite@5.0.12) + version: 3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)(vite@5.1.3) '@astrojs/sitemap': specifier: ^3.0.5 version: 3.0.5 @@ -21,8 +21,8 @@ dependencies: specifier: ^0.7.1 version: 0.7.1(nanostores@0.9.5)(react@18.2.0) '@types/react': - specifier: ^18.2.55 - version: 18.2.55 + specifier: ^18.2.56 + version: 18.2.58 '@types/react-dom': specifier: ^18.2.19 version: 18.2.19 @@ -45,8 +45,8 @@ dependencies: specifier: ^3.0.5 version: 3.0.5 lucide-react: - specifier: ^0.331.0 - version: 0.331.0(react@18.2.0) + specifier: ^0.334.0 + version: 0.334.0(react@18.2.0) nanoid: specifier: ^5.0.5 version: 5.0.5 @@ -73,7 +73,7 @@ dependencies: version: 18.2.0(react@18.2.0) reactflow: specifier: ^11.10.4 - version: 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + version: 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) rehype-external-links: specifier: ^3.0.0 version: 3.0.0 @@ -90,8 +90,8 @@ dependencies: specifier: ^3.4.1 version: 3.4.1 zustand: - specifier: ^4.5.0 - version: 4.5.0(@types/react@18.2.55)(react@18.2.0) + specifier: ^4.5.1 + version: 4.5.1(@types/react@18.2.58)(react@18.2.0) devDependencies: '@playwright/test': @@ -185,7 +185,7 @@ packages: prismjs: 1.29.0 dev: false - /@astrojs/react@3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0)(vite@5.0.12): + /@astrojs/react@3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)(vite@5.1.3): resolution: {integrity: sha512-uGRIwKMAn7tva2vxXMyoVIGxWFr0rjZ8ZWIlkTG/vIpnAjD2nM8Cz6B8j7yzj176jvl6gZ6xTbTVPm09aeK0Yw==} engines: {node: '>=18.14.1'} peerDependencies: @@ -194,9 +194,9 @@ packages: react: ^17.0.2 || ^18.0.0 react-dom: ^17.0.2 || ^18.0.0 dependencies: - '@types/react': 18.2.55 + '@types/react': 18.2.58 '@types/react-dom': 18.2.19 - '@vitejs/plugin-react': 4.2.1(vite@5.0.12) + '@vitejs/plugin-react': 4.2.1(vite@5.1.3) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ultrahtml: 1.5.2 @@ -1102,39 +1102,39 @@ packages: config-chain: 1.1.13 dev: false - /@reactflow/background@11.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /@reactflow/background@11.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-byj/G9pEC8tN0wT/ptcl/LkEP/BBfa33/SvBkqE4XwyofckqF87lKp573qGlisfnsijwAbpDlf81PuFL41So4Q==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) + zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0) transitivePeerDependencies: - '@types/react' - immer dev: false - /@reactflow/controls@11.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /@reactflow/controls@11.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-e8nWplbYfOn83KN1BrxTXS17+enLyFnjZPbyDgHSRLtI5ZGPKF/8iRXV+VXb2LFVzlu4Wh3la/pkxtfP/0aguA==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) + zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0) transitivePeerDependencies: - '@types/react' - immer dev: false - /@reactflow/core@11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /@reactflow/core@11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-j3i9b2fsTX/sBbOm+RmNzYEFWbNx4jGWGuGooh2r1jQaE2eV+TLJgiG/VNOp0q5mBl9f6g1IXs3Gm86S9JfcGw==} peerDependencies: react: '>=17' @@ -1150,19 +1150,19 @@ packages: d3-zoom: 3.0.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) + zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0) transitivePeerDependencies: - '@types/react' - immer dev: false - /@reactflow/minimap@11.7.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /@reactflow/minimap@11.7.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-le95jyTtt3TEtJ1qa7tZ5hyM4S7gaEQkW43cixcMOZLu33VAdc2aCpJg/fXcRrrf7moN2Mbl9WIMNXUKsp5ILA==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) '@types/d3-selection': 3.0.10 '@types/d3-zoom': 3.0.8 classcat: 5.0.4 @@ -1170,41 +1170,41 @@ packages: d3-zoom: 3.0.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) + zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0) transitivePeerDependencies: - '@types/react' - immer dev: false - /@reactflow/node-resizer@2.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /@reactflow/node-resizer@2.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-HfickMm0hPDIHt9qH997nLdgLt0kayQyslKE0RS/GZvZ4UMQJlx/NRRyj5y47Qyg0NnC66KYOQWDM9LLzRTnUg==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 d3-drag: 3.0.0 d3-selection: 3.0.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) + zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0) transitivePeerDependencies: - '@types/react' - immer dev: false - /@reactflow/node-toolbar@1.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /@reactflow/node-toolbar@1.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-VmgxKmToax4sX1biZ9LXA7cj/TBJ+E5cklLGwquCCVVxh+lxpZGTBF3a5FJGVHiUNBBtFsC8ldcSZIK4cAlQww==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) + zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0) transitivePeerDependencies: - '@types/react' - immer @@ -1700,11 +1700,11 @@ packages: /@types/react-dom@18.2.19: resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==} dependencies: - '@types/react': 18.2.55 + '@types/react': 18.2.58 dev: false - /@types/react@18.2.55: - resolution: {integrity: sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==} + /@types/react@18.2.58: + resolution: {integrity: sha512-TaGvMNhxvG2Q0K0aYxiKfNDS5m5ZsoIBBbtfUorxdH4NGSXIlYvZxLJI+9Dd3KjeB3780bciLyAb7ylO8pLhPw==} dependencies: '@types/prop-types': 15.7.11 '@types/scheduler': 0.16.8 @@ -1733,7 +1733,7 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: false - /@vitejs/plugin-react@4.2.1(vite@5.0.12): + /@vitejs/plugin-react@4.2.1(vite@5.1.3): resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -1744,7 +1744,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.0.12 + vite: 5.1.3 transitivePeerDependencies: - supports-color dev: false @@ -3996,8 +3996,8 @@ packages: engines: {node: '>=12'} dev: false - /lucide-react@0.331.0(react@18.2.0): - resolution: {integrity: sha512-CHFJ0ve9vaZ7bB2VRAl27SlX1ELh6pfNC0jS96qGpPEEzLkLDGq4pDBFU8RhOoRMqsjXqTzLm9U6bZ1OcIHq7Q==} + /lucide-react@0.334.0(react@18.2.0): + resolution: {integrity: sha512-y0Rv/Xx6qAq4FutZ3L/efl3O9vl6NC/1p0YOg6mBfRbQ4k1JCE2rz0rnV7WC8Moxq1RY99vLATvjcqUegGJTvA==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 dependencies: @@ -5543,18 +5543,18 @@ packages: loose-envify: 1.4.0 dev: false - /reactflow@11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): + /reactflow@11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-0CApYhtYicXEDg/x2kvUHiUk26Qur8lAtTtiSlptNKuyEuGti6P1y5cS32YGaUoDMoCqkm/m+jcKkfMOvSCVRA==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/background': 11.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/controls': 11.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/minimap': 11.7.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/node-resizer': 2.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/node-toolbar': 1.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/background': 11.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/controls': 11.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/minimap': 11.7.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-resizer': 2.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-toolbar': 1.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -6745,41 +6745,6 @@ packages: vfile-message: 4.0.2 dev: false - /vite@5.0.12: - resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.19.11 - postcss: 8.4.33 - rollup: 4.9.6 - optionalDependencies: - fsevents: 2.3.3 - dev: false - /vite@5.1.3: resolution: {integrity: sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==} engines: {node: ^18.0.0 || >=20.0.0} @@ -6964,8 +6929,8 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false - /zustand@4.5.0(@types/react@18.2.55)(react@18.2.0): - resolution: {integrity: sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==} + /zustand@4.5.1(@types/react@18.2.58)(react@18.2.0): + resolution: {integrity: sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg==} engines: {node: '>=12.7.0'} peerDependencies: '@types/react': '>=16.8' @@ -6979,7 +6944,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.55 + '@types/react': 18.2.58 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) dev: false diff --git a/src/components/GuideHeader.astro b/src/components/GuideHeader.astro index f11662573..089381755 100644 --- a/src/components/GuideHeader.astro +++ b/src/components/GuideHeader.astro @@ -6,28 +6,32 @@ export interface Props { } const { guide } = Astro.props; -const { frontmatter } = guide; -const { author } = frontmatter; +const { frontmatter, author } = guide; --- -
+
-

+

{frontmatter.title}

-
diff --git a/src/components/GuideListItem.astro b/src/components/GuideListItem.astro index 45658649b..118c66dfb 100644 --- a/src/components/GuideListItem.astro +++ b/src/components/GuideListItem.astro @@ -1,5 +1,5 @@ --- -import type { GuideFileType } from "../lib/guide"; +import type { GuideFileType } from '../lib/guide'; export interface Props { guide: GuideFileType; @@ -11,30 +11,34 @@ const { frontmatter, id } = guide; - + {frontmatter.title} { frontmatter.isNew && ( - + New - ) } - diff --git a/src/data/authors/fernando.md b/src/data/authors/fernando.md new file mode 100644 index 000000000..8e936f656 --- /dev/null +++ b/src/data/authors/fernando.md @@ -0,0 +1,11 @@ +--- +name: 'Fernando Doglio' +imageUrl: '/authors/fernando.jpeg' +social: + twitter: 'https://twitter.com/deleteman123' + linkedin: 'https://www.linkedin.com/in/fernandodoglio' +--- + +With two decades of experience in Software Development, Fernando Doglio excels in diverse languages like Ruby, Perl, PHP, Python, and JavaScript. He's led teams in crafting scalable architectures for both in-house and cloud infrastructures. + +An author of 8 technical books and over 250 articles, Fernando's current role as a Dev Advocate allows him to blend his passion for coding with content creation, enhancing developer experiences with products through engaging outreach. \ No newline at end of file diff --git a/src/data/authors/kamran.md b/src/data/authors/kamran.md new file mode 100644 index 000000000..8e5f7c9ee --- /dev/null +++ b/src/data/authors/kamran.md @@ -0,0 +1,13 @@ +--- +name: 'Kamran Ahmed' +imageUrl: '/authors/kamran.jpeg' +social: + linkedin: 'https://www.linkedin.com/in/kamrify' + twitter: 'https://twitter.com/kamrify' + github: 'https://github.com/kamranahmedse' + website: 'https://kamranahmed.info' +--- + +Kamran is the founder of **roadmap.sh**. He has a decade long experience working mostly with startups and scale-ups. Over the years, he has worked with a variety of technologies in a variety of domains and have worn several different hats. He is working full time on roadmap.sh at the moment. + +He is also a Google Developer Expert and a GitHub Star. He is a huge proponent of open-source, and has authored several popular open-source projects. He is [the second most starred developer](https://twitter.com/kamrify/status/1750345095587754382) on GitHub globally. \ No newline at end of file diff --git a/src/data/guides/asymptotic-notation.md b/src/data/guides/asymptotic-notation.md index 4690e94fa..b7db091bb 100644 --- a/src/data/guides/asymptotic-notation.md +++ b/src/data/guides/asymptotic-notation.md @@ -1,10 +1,7 @@ --- title: 'Asymptotic Notation' description: 'Learn the basics of measuring the time and space complexity of algorithms' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Asymptotic Notation - roadmap.sh' description: 'Learn the basics of measuring the time and space complexity of algorithms' diff --git a/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md b/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md index 7718502f8..23852c97d 100644 --- a/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md +++ b/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md @@ -1,10 +1,7 @@ --- title: 'Async and Defer Script Loading' description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Async and Defer Script Loading - roadmap.sh' description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.' diff --git a/src/data/guides/backend-languages.md b/src/data/guides/backend-languages.md index a273a2c5e..3c57108e0 100644 --- a/src/data/guides/backend-languages.md +++ b/src/data/guides/backend-languages.md @@ -1,10 +1,7 @@ --- title: 'The 5 Best Backend Development Languages to Master (2024)' description: 'Discover the best backend development languages to master in 2024.' -author: - name: 'Fernando Doglio' - url: 'https://twitter.com/deleteman123' - imageUrl: '/authors/fernando.jpeg' +authorId: fernando excludedBySlug: '/backend/languages' seo: title: 'The 5 Best Backend Development Languages to Master (2024)' @@ -116,9 +113,9 @@ What makes Python extra appealing, especially for beginners, is the fact that re One of Python's standout features is its beginner-friendly syntax, making it an ideal language for those new to programming. The emphasis on readability and the absence of complex syntax (for the most part), eases the learning curve, enabling new developers to quickly grasp fundamental concepts. -Python's community plays a critical role in its accessibility. Abundant learning resources, tutorials, and documentation are readily available, empowering beginners to progress from basic programming principles to advanced backend development seamlessly. Online platforms like Codecademy, Coursera, realpython.com, and even Google offer comprehensive courses tailored to all skill levels. +Python's community plays a critical role in its accessibility. Abundant learning resources, tutorials, and documentation are readily available, empowering beginners to progress from basic programming principles to advanced backend development seamlessly. Online platforms like Codecademy, Coursera, realpython.com, and even Google offer comprehensive courses tailored to all skill levels. -#### Practical Applications and Popular Frameworks +#### Practical Applications and Popular Frameworks Python's versatility is evident in its applicability across a spectrum of industries, from web development and data science to artificial intelligence and automation. In the context of backend development, Python shines brightly with its two standout frameworks: [Django](https://www.djangoproject.com/) and [Flask](https://github.com/pallets/flask). @@ -154,7 +151,7 @@ Java has a massive presence and for good reason (according to [JetBrain’s surv #### Is it worth learning Java? -Now, learning Java, (a strongly typed, object oriented programming language (OOP), is a journey worth taking, but it's not a walk in the park. It's a bit like climbing a mountain – you start at the bottom with the basics, and as you ascend, you get into the nitty-gritty of things like object-oriented programming. The process will force you to learn a lot, which is a great thing, by the end you’ll have a lot of understanding of mechanics and concepts around OOP that can be extrapolated into other languages. However, that can also be overwhelming to some developers who just want to learn by building mini-projects. In those situations, the learning curve of Java might be too long (not steep, but long because there is a lot more to cover than with alternatives such as Python or JavaScript). +Now, learning Java, (a strongly typed, object oriented programming language (OOP), is a journey worth taking, but it's not a walk in the park. It's a bit like climbing a mountain – you start at the bottom with the basics, and as you ascend, you get into the nitty-gritty of things like object-oriented programming. The process will force you to learn a lot, which is a great thing, by the end you’ll have a lot of understanding of mechanics and concepts around OOP that can be extrapolated into other languages. However, that can also be overwhelming to some developers who just want to learn by building mini-projects. In those situations, the learning curve of Java might be too long (not steep, but long because there is a lot more to cover than with alternatives such as Python or JavaScript). That said, the community is big and there are tons of resources, from online courses to forums, helping you navigate the Java landscape. And good reason, considering Java has been around for quite a while. @@ -197,7 +194,7 @@ If you were to rank languages based on the amount of content out there to learn #### Key Frameworks and Development Tools -Now, let's talk about frameworks. In the case of JavaScript, this topic is so varied that recommending a single option for someone just getting started is really hard. +Now, let's talk about frameworks. In the case of JavaScript, this topic is so varied that recommending a single option for someone just getting started is really hard. For example, if you want to go frontend agnostic, or in other words, you don’t care about the technology being used to develop the client side of your app, then a good starting option would be [Express.js](https://expressjs.com/). This framework used to be the industry standard. And while that’s no longer the case, it’s still a perfect first choice if you’re looking for something with the required functionality to make your life a lot easier. @@ -205,7 +202,7 @@ Now, if on the other hand, you’re looking to build the frontend and the backen #### Does it make sense to pick up JavaScript as a backend language? -The answer to this question is always going to be “yes”, whether you’re coming from the frontend and you already have JS experience or if you’re picking it up from scratch. In fact, according to [StackOverflow’s 2023 survey, JavaScript is the most used language by professionals](https://survey.stackoverflow.co/2023/#most-popular-technologies-language-prof) (with 65.85% of the votes). +The answer to this question is always going to be “yes”, whether you’re coming from the frontend and you already have JS experience or if you’re picking it up from scratch. In fact, according to [StackOverflow’s 2023 survey, JavaScript is the most used language by professionals](https://survey.stackoverflow.co/2023/#most-popular-technologies-language-prof) (with 65.85% of the votes). ![JavaScript Interest](/guides/backend-languages/javascript-interest.png) @@ -234,7 +231,7 @@ While there might not be a downside to picking JS, there is no perfect language ### PHP -Now, if you’re looking for something very well established in the web development industry, just like Java but with a shorter learning curve, then you’re probably looking for PHP. +Now, if you’re looking for something very well established in the web development industry, just like Java but with a shorter learning curve, then you’re probably looking for PHP. > As a note about PHP’s relevancy, while many developers might claim that PHP is a dying tech, according to [W3Techs, over 75% of websites with a backend use PHP](https://w3techs.com/technologies/details/pl-php). @@ -242,7 +239,7 @@ It's the glue that holds a ton of websites together, and its longevity in the we #### Ease of Mastery and Vast Library Support -If you're diving into PHP, you wouldn’t be so wrong (no matter what others might tell you). It's got a gentle learning curve, which means you can start building things pretty quickly. Getting everything set up and working will probably take you 10 minutes, and you’ll be writing your first “hello world” 5 minutes after that. +If you're diving into PHP, you wouldn’t be so wrong (no matter what others might tell you). It's got a gentle learning curve, which means you can start building things pretty quickly. Getting everything set up and working will probably take you 10 minutes, and you’ll be writing your first “hello world” 5 minutes after that. The vast community support and an ocean of online resources make mastering PHP a breeze. Plus, its library support is like having a toolkit that's always expanding – you'll find what you need, whether you're wrangling databases, handling forms, or making your website dance with dynamic content. @@ -250,9 +247,9 @@ If you’re looking to pick up PHP, look for the LAMP stack, which stands for ** #### Modern PHP Frameworks and Their Impact -If we’re talking about PHP frameworks, then we gotta talk about [Laravel](https://laravel.com/) and [Symfony](https://symfony.com/). They are like the rockstars of the modern PHP world. +If we’re talking about PHP frameworks, then we gotta talk about [Laravel](https://laravel.com/) and [Symfony](https://symfony.com/). They are like the rockstars of the modern PHP world. -Laravel comes with a lot of tools and features that help you speed up your development process. On the other side, Symfony has a modular architecture, making it a solid choice for projects of all sizes. +Laravel comes with a lot of tools and features that help you speed up your development process. On the other side, Symfony has a modular architecture, making it a solid choice for projects of all sizes. These frameworks showcase how PHP has evolved, staying relevant and powerful in the ever-changing landscape of web development. @@ -337,7 +334,7 @@ Lucky for you, if you’re reading this, that means you’ve found the most comp ### Guided Learning: From Online Courses to Bootcamps -Online courses and bootcamps serve as invaluable companions on your learning expedition. Platforms like Udemy, Coursera, and freeCodeCamp offer comprehensive backend development courses. +Online courses and bootcamps serve as invaluable companions on your learning expedition. Platforms like Udemy, Coursera, and freeCodeCamp offer comprehensive backend development courses. These resources not only cover programming languages like Python, Java, or JavaScript but also dive deep into frameworks like Django, Express.js, or Laravel. For those seeking a more immersive experience, coding bootcamps provide intensive, hands-on training to fast-track your backend development skills. @@ -345,7 +342,7 @@ Whatever choice you go for, make sure you’re not following trends or just copy ### Building Community Connections for Learning Support -Joining developer communities (there are several on Twitter for example), forums like Stack Overflow, or participating in social media groups dedicated to backend development creates a network of support. +Joining developer communities (there are several on Twitter for example), forums like Stack Overflow, or participating in social media groups dedicated to backend development creates a network of support. Engaging with experienced developers, sharing challenges, and seeking advice fosters a collaborative learning environment. Attend local meetups or virtual events if you can to connect with professionals in the field, gaining insights and building relationships that can prove invaluable throughout your journey. @@ -368,7 +365,7 @@ As you accumulate skills and knowledge, showcase your journey through a well-cra When it comes to deciding where to publish this portfolio, you have some options, such as directly on your GitHub profile (if you have one), or perhaps on your own personal website where you can share some design thoughts about each project along with the code. -In the end, the important thing is that you should be sharing your experience somewhere, especially when you don’t have working experience in the field. +In the end, the important thing is that you should be sharing your experience somewhere, especially when you don’t have working experience in the field. ### Conclusion @@ -383,12 +380,3 @@ In the end, there are many backend programming languages to choose from, and wha You’re the one who gets to decide, but just know that no matter what you choose, getting started in backend development is a one-way street. You’ll be learning from this moment on, and you’ll be jumping from one language to the other as the field evolves. Remember that there is a very detailed version of a [backend roadmap here](https://roadmap.sh/backend), it might be a great place to get started! And if you’re also interested in frontend development, there is an [equally handy roadmap](https://roadmap.sh/frontend) here as well! - - - - - - - - - diff --git a/src/data/guides/basic-authentication.md b/src/data/guides/basic-authentication.md index bc344e51a..9b5fd3980 100644 --- a/src/data/guides/basic-authentication.md +++ b/src/data/guides/basic-authentication.md @@ -1,10 +1,7 @@ --- title: 'Basic Authentication' description: 'Understand what is basic authentication and how it is implemented' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Basic Authentication - roadmap.sh' description: 'Understand what is basic authentication and how it is implemented' diff --git a/src/data/guides/basics-of-authentication.md b/src/data/guides/basics-of-authentication.md index 9605e1867..5826dc223 100644 --- a/src/data/guides/basics-of-authentication.md +++ b/src/data/guides/basics-of-authentication.md @@ -1,10 +1,7 @@ --- title: 'Basics of Authentication' description: 'Learn the basics of Authentication and Authorization' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Basics of Authentication - roadmap.sh' description: 'Learn the basics of Authentication and Authorization' diff --git a/src/data/guides/big-o-notation.md b/src/data/guides/big-o-notation.md index b5dbad25c..8eb6c8ae7 100644 --- a/src/data/guides/big-o-notation.md +++ b/src/data/guides/big-o-notation.md @@ -1,10 +1,7 @@ --- title: 'Big-O Notation' description: 'Easy to understand explanation of Big-O notation without any fancy terms' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Big-O Notation - roadmap.sh' description: 'Easy to understand explanation of Big-O notation without any fancy terms' diff --git a/src/data/guides/character-encodings.md b/src/data/guides/character-encodings.md index 6d4dcf127..268390d2d 100644 --- a/src/data/guides/character-encodings.md +++ b/src/data/guides/character-encodings.md @@ -1,10 +1,7 @@ --- title: 'Character Encodings' description: 'Covers the basics of character encodings and explains ASCII vs Unicode' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Character Encodings - roadmap.sh' description: 'Covers the basics of character encodings and explains ASCII vs Unicode' diff --git a/src/data/guides/ci-cd.md b/src/data/guides/ci-cd.md index bfd9cda06..135c62b69 100644 --- a/src/data/guides/ci-cd.md +++ b/src/data/guides/ci-cd.md @@ -1,10 +1,7 @@ --- title: 'What is CI and CD?' description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'What is CI and CD? - roadmap.sh' description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.' diff --git a/src/data/guides/consistency-patterns-in-distributed-systems.md b/src/data/guides/consistency-patterns-in-distributed-systems.md index 25b69c2c1..1f8f5ee2a 100644 --- a/src/data/guides/consistency-patterns-in-distributed-systems.md +++ b/src/data/guides/consistency-patterns-in-distributed-systems.md @@ -1,10 +1,7 @@ --- title: 'Consistency Patterns' description: 'Everything you need to know about Week, Strong and Eventual Consistency' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Consistency Patterns - roadmap.sh' description: 'Everything you need to know about Week, Strong and Eventual Consistency' diff --git a/src/data/guides/design-patterns-for-humans.md b/src/data/guides/design-patterns-for-humans.md index 57cc96169..d3eace516 100644 --- a/src/data/guides/design-patterns-for-humans.md +++ b/src/data/guides/design-patterns-for-humans.md @@ -1,10 +1,7 @@ --- title: 'Design Patterns for Humans' description: 'A language agnostic, ultra-simplified explanation to design patterns' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Design Patterns for Humans - roadmap.sh' description: 'A language agnostic, ultra-simplified explanation to design patterns' diff --git a/src/data/guides/dhcp-in-one-picture.md b/src/data/guides/dhcp-in-one-picture.md index 5c9179378..b32df3362 100644 --- a/src/data/guides/dhcp-in-one-picture.md +++ b/src/data/guides/dhcp-in-one-picture.md @@ -1,10 +1,7 @@ --- title: 'DHCP in One Picture' description: 'Here is what happens when a new device joins the network.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'DHCP in One Picture - roadmap.sh' description: 'Here is what happens when a new device joins the network.' diff --git a/src/data/guides/dns-in-one-picture.md b/src/data/guides/dns-in-one-picture.md index 8cf7bf484..8acb42731 100644 --- a/src/data/guides/dns-in-one-picture.md +++ b/src/data/guides/dns-in-one-picture.md @@ -1,10 +1,7 @@ --- title: 'DNS in One Picture' description: 'Quick illustrative guide on how a website is found on the internet.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'DNS in One Picture - roadmap.sh' description: 'Quick illustrative guide on how a website is found on the internet.' diff --git a/src/data/guides/free-resources-to-learn-llms.md b/src/data/guides/free-resources-to-learn-llms.md index e2ea0cd60..b19ef2982 100644 --- a/src/data/guides/free-resources-to-learn-llms.md +++ b/src/data/guides/free-resources-to-learn-llms.md @@ -1,10 +1,7 @@ --- title: '5 Free Resources to Master LLMs' description: 'Dive into the world of LLMs with these free resources' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: '5 Free Resources to Master Language Models (LLMs) - roadmap.sh' description: 'Looking to dive into the fascinating world of Language Models (LLMs)? Discover the top 5 free resources that will help you learn and excel in understanding LLMs. From comprehensive tutorials to interactive courses, this blog post provides you with the ultimate guide to sharpen your skills and unravel the potential of language models. Start your journey today and become a pro in LLMs without spending a dime!' diff --git a/src/data/guides/history-of-javascript.md b/src/data/guides/history-of-javascript.md index be9cc030c..637f71df4 100644 --- a/src/data/guides/history-of-javascript.md +++ b/src/data/guides/history-of-javascript.md @@ -1,10 +1,7 @@ --- title: 'Brief History of JavaScript' description: 'How JavaScript was introduced and evolved over the years' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Brief History of JavaScript - roadmap.sh' description: 'How JavaScript was introduced and evolved over the years' diff --git a/src/data/guides/how-to-setup-a-jump-server.md b/src/data/guides/how-to-setup-a-jump-server.md index 70642b784..63bcd8f65 100644 --- a/src/data/guides/how-to-setup-a-jump-server.md +++ b/src/data/guides/how-to-setup-a-jump-server.md @@ -1,10 +1,7 @@ --- title: 'Jump Servers: What, Why and How' description: 'Learn what is a Jump Server and how to set it up for SSH access.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Jump Servers: What, Why and How - roadmap.sh' description: 'Learn what is a Jump Server and how to set it up for SSH access.' diff --git a/src/data/guides/http-basic-authentication.md b/src/data/guides/http-basic-authentication.md index 833335990..25b52655b 100644 --- a/src/data/guides/http-basic-authentication.md +++ b/src/data/guides/http-basic-authentication.md @@ -1,10 +1,7 @@ --- title: 'HTTP Basic Authentication' description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'HTTP Basic Authentication - roadmap.sh' description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js' diff --git a/src/data/guides/http-caching.md b/src/data/guides/http-caching.md index 41ef7ba89..bb8834925 100644 --- a/src/data/guides/http-caching.md +++ b/src/data/guides/http-caching.md @@ -1,10 +1,7 @@ --- title: 'HTTP Caching' description: 'Everything you need to know about web caching' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'HTTP Caching - roadmap.sh' description: 'Everything you need to know about web caching' diff --git a/src/data/guides/introduction-to-llms.md b/src/data/guides/introduction-to-llms.md index dc4f17ea7..b835bc512 100644 --- a/src/data/guides/introduction-to-llms.md +++ b/src/data/guides/introduction-to-llms.md @@ -1,10 +1,7 @@ --- title: 'Introduction to LLMs' description: 'What are LLMs, how does ChatGPT and other LLMs work?' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Introduction to LLMs - roadmap.sh' description: 'What are LLMs, how does ChatGPT and other LLMs work?' diff --git a/src/data/guides/journey-to-http2.md b/src/data/guides/journey-to-http2.md index 153f56ef8..209c5d2e6 100644 --- a/src/data/guides/journey-to-http2.md +++ b/src/data/guides/journey-to-http2.md @@ -1,10 +1,7 @@ --- title: 'Journey to HTTP/2' description: 'The evolution of HTTP. How it all started and where we stand today' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Journey to HTTP/2 - roadmap.sh' description: 'The evolution of HTTP. How it all started and where we stand today' diff --git a/src/data/guides/jwt-authentication.md b/src/data/guides/jwt-authentication.md index 4d09a3b73..518a9f95d 100644 --- a/src/data/guides/jwt-authentication.md +++ b/src/data/guides/jwt-authentication.md @@ -1,10 +1,7 @@ --- title: 'JWT Authentication' description: 'Understand what is JWT authentication and how is it implemented' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'JWT Authentication - roadmap.sh' description: 'Understand what is JWT authentication and how is it implemented' diff --git a/src/data/guides/levels-of-seniority.md b/src/data/guides/levels-of-seniority.md index f5c71e946..eb7c2f42c 100644 --- a/src/data/guides/levels-of-seniority.md +++ b/src/data/guides/levels-of-seniority.md @@ -1,10 +1,7 @@ --- title: 'Levels of Seniority' description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Levels of Seniority - roadmap.sh' description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?' diff --git a/src/data/guides/oauth.md b/src/data/guides/oauth.md index f56fde7ea..6834d67d7 100644 --- a/src/data/guides/oauth.md +++ b/src/data/guides/oauth.md @@ -1,10 +1,7 @@ --- title: 'OAuth — Open Authorization' description: 'Learn and understand what is OAuth and how it works' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'OAuth — Open Authorization - roadmap.sh' description: 'Learn and understand what is OAuth and how it works' diff --git a/src/data/guides/random-numbers.md b/src/data/guides/random-numbers.md index 15d3d221a..f193dd15a 100644 --- a/src/data/guides/random-numbers.md +++ b/src/data/guides/random-numbers.md @@ -1,10 +1,7 @@ --- title: 'Random Numbers: Are they?' description: 'Learn how they are generated and why they may not be truly random.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Random Numbers: Are they? - roadmap.sh' description: 'Learn how they are generated and why they may not be truly random.' diff --git a/src/data/guides/scaling-databases.md b/src/data/guides/scaling-databases.md index bfc6b90e3..af2f49df8 100644 --- a/src/data/guides/scaling-databases.md +++ b/src/data/guides/scaling-databases.md @@ -1,10 +1,7 @@ --- title: 'Scaling Databases' description: 'Learn the ups and downs of different database scaling strategies' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Scaling Databases - roadmap.sh' description: 'Learn the ups and downs of different database scaling strategies' diff --git a/src/data/guides/session-authentication.md b/src/data/guides/session-authentication.md index cb91ece61..c86d5f1af 100644 --- a/src/data/guides/session-authentication.md +++ b/src/data/guides/session-authentication.md @@ -1,10 +1,7 @@ --- title: 'Session Based Authentication' description: 'Understand what is session based authentication and how it is implemented' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Session Based Authentication - roadmap.sh' description: 'Understand what is session based authentication and how it is implemented' diff --git a/src/data/guides/session-based-authentication.md b/src/data/guides/session-based-authentication.md index e6bba3247..cc30c62b1 100644 --- a/src/data/guides/session-based-authentication.md +++ b/src/data/guides/session-based-authentication.md @@ -1,10 +1,7 @@ --- title: 'Session Based Authentication' description: 'Learn what is Session Based Authentication and how to implement it in Node.js' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Session Based Authentication - roadmap.sh' description: 'Learn what is Session Based Authentication and how to implement it in Node.js' diff --git a/src/data/guides/setup-and-auto-renew-ssl-certificates.md b/src/data/guides/setup-and-auto-renew-ssl-certificates.md index 3acbdbc87..0f7ef3750 100644 --- a/src/data/guides/setup-and-auto-renew-ssl-certificates.md +++ b/src/data/guides/setup-and-auto-renew-ssl-certificates.md @@ -1,10 +1,7 @@ --- title: "Guide to Let's Encrypt SSL Setup" description: "Learn how to protect your website using Let's Encrypt SSL Certificates." -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: "Guide to Let's Encrypt SSL Setup - roadmap.sh" description: "Learn how to protect your website using Let's Encrypt SSL Certificates." diff --git a/src/data/guides/single-command-database-setup.md b/src/data/guides/single-command-database-setup.md index 129c8a5e8..e280f8819 100644 --- a/src/data/guides/single-command-database-setup.md +++ b/src/data/guides/single-command-database-setup.md @@ -1,10 +1,7 @@ --- title: 'Single Command Database Setup' description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Single Command Database Setup - roadmap.sh' description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command' diff --git a/src/data/guides/ssl-tls-https-ssh.md b/src/data/guides/ssl-tls-https-ssh.md index 1832b62ba..b21b140b7 100644 --- a/src/data/guides/ssl-tls-https-ssh.md +++ b/src/data/guides/ssl-tls-https-ssh.md @@ -1,10 +1,7 @@ --- title: 'SSL vs TLS vs SSH' description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'SSL vs TLS vs SSH - roadmap.sh' description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH' diff --git a/src/data/guides/sso.md b/src/data/guides/sso.md index 6d3987015..1dd61cef7 100644 --- a/src/data/guides/sso.md +++ b/src/data/guides/sso.md @@ -1,10 +1,7 @@ --- title: 'SSO — Single Sign On' description: 'Learn the basics of SAML and understand how does Single Sign On work.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'SSO — Single Sign On - roadmap.sh' description: 'Learn the basics of SAML and understand how does Single Sign On work.' diff --git a/src/data/guides/token-authentication.md b/src/data/guides/token-authentication.md index fcfac7986..bb82324a1 100644 --- a/src/data/guides/token-authentication.md +++ b/src/data/guides/token-authentication.md @@ -1,10 +1,7 @@ --- title: 'Token Based Authentication' description: 'Understand what is token based authentication and how it is implemented' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Token Based Authentication - roadmap.sh' description: 'Understand what is token based authentication and how it is implemented' diff --git a/src/data/guides/unfamiliar-codebase.md b/src/data/guides/unfamiliar-codebase.md index c6c07d809..41396c3e2 100644 --- a/src/data/guides/unfamiliar-codebase.md +++ b/src/data/guides/unfamiliar-codebase.md @@ -1,10 +1,7 @@ --- title: 'Unfamiliar Codebase' description: 'Tips on getting familiar with an unfamiliar codebase' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'Unfamiliar Codebase - roadmap.sh' description: 'Tips on getting familiar with an unfamiliar codebase' diff --git a/src/data/guides/what-are-web-vitals.md b/src/data/guides/what-are-web-vitals.md index 00a8138fe..bdc782d81 100644 --- a/src/data/guides/what-are-web-vitals.md +++ b/src/data/guides/what-are-web-vitals.md @@ -1,10 +1,7 @@ --- title: 'What are Web Vitals?' description: 'Learn what are the core web vitals and how to measure them.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'What are Web Vitals? - roadmap.sh' description: 'Learn what are the core web vitals and how to measure them.' diff --git a/src/data/guides/what-is-internet.md b/src/data/guides/what-is-internet.md index e9a58773e..044676320 100644 --- a/src/data/guides/what-is-internet.md +++ b/src/data/guides/what-is-internet.md @@ -1,10 +1,7 @@ --- title: 'How does the internet work?' description: 'Learn the basics of internet and everything involved with this short video series' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'How does the internet work? - roadmap.sh' description: 'Learn the basics of internet and everything involved with this short video series' diff --git a/src/data/guides/what-is-sli-slo-sla.md b/src/data/guides/what-is-sli-slo-sla.md index c3bc63fc3..53e2cf386 100644 --- a/src/data/guides/what-is-sli-slo-sla.md +++ b/src/data/guides/what-is-sli-slo-sla.md @@ -1,10 +1,7 @@ --- title: 'SLIs, SLOs and SLAs' description: 'Learn what are different indicators for performance identification of any service.' -author: - name: 'Kamran Ahmed' - url: 'https://twitter.com/kamrify' - imageUrl: '/authors/kamranahmedse.jpeg' +authorId: 'kamran' seo: title: 'SLIs, SLOs and SLAs - roadmap.sh' description: 'Learn what are different indicators for performance identification of any service.' diff --git a/src/env.d.ts b/src/env.d.ts index 2cc9d6465..057b60995 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,4 +1,3 @@ -/// import 'astro/client'; interface ImportMetaEnv { diff --git a/src/icons/github.svg b/src/icons/github.svg index 44124c848..020512f58 100644 --- a/src/icons/github.svg +++ b/src/icons/github.svg @@ -1 +1 @@ - + diff --git a/src/icons/globe.svg b/src/icons/globe.svg new file mode 100644 index 000000000..9c33da5df --- /dev/null +++ b/src/icons/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/linkedin-2.svg b/src/icons/linkedin-2.svg new file mode 100644 index 000000000..7013c1e4e --- /dev/null +++ b/src/icons/linkedin-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/lib/author.ts b/src/lib/author.ts new file mode 100644 index 000000000..86afb2a43 --- /dev/null +++ b/src/lib/author.ts @@ -0,0 +1,73 @@ +import type { MarkdownFileType } from './file'; + +export interface AuthorFrontmatter { + name: string; + imageUrl: string; + social: { + twitter: string; + github: string; + linkedin: string; + website: string; + }; +} + +export type AuthorFileType = MarkdownFileType & { + id: string; +}; + +function authorPathToId(filePath: string): string { + const fileName = filePath.split('/').pop() || ''; + + return fileName.replace('.md', ''); +} + +/** + * Gets the IDs of all the authors available on the website + * + * @returns string[] Array of author IDs + */ +export async function getAuthorIds() { + const authorFiles = import.meta.glob( + '/src/data/authors/*.md', + { + eager: true, + }, + ); + + console.log(Object.keys(authorFiles)); + return Object.keys(authorFiles).map(authorPathToId); +} + +export async function getAllAuthors(): Promise { + const authorFilesMap: Record = + import.meta.glob('/src/data/authors/*.md', { + eager: true, + }); + + const authorFiles = Object.values(authorFilesMap); + + return authorFiles.map((authorFile) => ({ + ...authorFile, + id: authorPathToId(authorFile.file), + })); +} + +export async function getAuthorById(id: string): Promise { + const authorFilesMap: Record = + import.meta.glob('/src/data/authors/*.md', { + eager: true, + }); + + const authorFile = Object.values(authorFilesMap).find((authorFile) => { + return authorPathToId(authorFile.file) === id; + }); + + if (!authorFile) { + throw new Error(`Author with ID ${id} not found`); + } + + return { + ...authorFile, + id: authorPathToId(authorFile.file), + }; +} diff --git a/src/lib/guide.ts b/src/lib/guide.ts index 8bdfb678d..464d0e404 100644 --- a/src/lib/guide.ts +++ b/src/lib/guide.ts @@ -1,13 +1,10 @@ import type { MarkdownFileType } from './file'; +import { type AuthorFileType, getAllAuthors } from './author.ts'; export interface GuideFrontmatter { title: string; description: string; - author: { - name: string; - url: string; - imageUrl: string; - }; + authorId: string; canonicalUrl?: string; // alternate path where this guide has been published excludedBySlug?: string; @@ -27,6 +24,7 @@ export interface GuideFrontmatter { export type GuideFileType = MarkdownFileType & { id: string; + author: AuthorFileType; }; /** @@ -41,23 +39,33 @@ function guidePathToId(filePath: string): string { return fileName.replace('.md', ''); } +export async function getGuidesByAuthor( + authorId: string, +): Promise { + const allGuides = await getAllGuides(); + + return allGuides.filter((guide) => guide.author?.id === authorId); +} + /** * Gets all the guides sorted by the publishing date * @returns Promisifed guide files */ export async function getAllGuides(): Promise { // @ts-ignore - const guides = await import.meta.glob( - '/src/data/guides/*.md', - { - eager: true, - }, - ); + const guides = import.meta.glob('/src/data/guides/*.md', { + eager: true, + }); + + const allAuthors = await getAllAuthors(); const guideFiles = Object.values(guides) as GuideFileType[]; - const enrichedGuides = guideFiles.map((guideFile) => ({ + const enrichedGuides: GuideFileType[] = guideFiles.map((guideFile) => ({ ...guideFile, id: guidePathToId(guideFile.file), + author: allAuthors.find( + (author) => author.id === guideFile.frontmatter.authorId, + )!, })); return enrichedGuides.sort( diff --git a/src/lib/roadmap.ts b/src/lib/roadmap.ts index 6d12fe344..cb4983405 100644 --- a/src/lib/roadmap.ts +++ b/src/lib/roadmap.ts @@ -60,7 +60,7 @@ function roadmapPathToId(filePath: string): string { * @returns string[] Array of roadmap IDs */ export async function getRoadmapIds() { - const roadmapFiles = await import.meta.glob( + const roadmapFiles = import.meta.glob( '/src/data/roadmaps/*/*.md', { eager: true, @@ -79,14 +79,14 @@ export async function getRoadmapIds() { export async function getRoadmapsByTag( tag: string, ): Promise { - const roadmapFilesMap = await import.meta.glob( + const roadmapFilesMap = import.meta.glob( '/src/data/roadmaps/*/*.md', { eager: true, }, ); - const roadmapFiles = Object.values(roadmapFilesMap); + const roadmapFiles: RoadmapFileType[] = Object.values(roadmapFilesMap); const filteredRoadmaps = roadmapFiles .filter((roadmapFile) => roadmapFile.frontmatter.tags.includes(tag)) .map((roadmapFile) => ({ @@ -100,12 +100,10 @@ export async function getRoadmapsByTag( } export async function getRoadmapById(id: string): Promise { - const roadmapFilesMap = await import.meta.glob( - '/src/data/roadmaps/*/*.md', - { + const roadmapFilesMap: Record = + import.meta.glob('/src/data/roadmaps/*/*.md', { eager: true, - }, - ); + }); const roadmapFile = Object.values(roadmapFilesMap).find((roadmapFile) => { return roadmapPathToId(roadmapFile.file) === id; diff --git a/src/lib/video.ts b/src/lib/video.ts index 22206bc8a..d0eeb9ec6 100644 --- a/src/lib/video.ts +++ b/src/lib/video.ts @@ -1,4 +1,5 @@ import type { MarkdownFileType } from './file'; +import type {AuthorFileType} from "./author.ts"; export interface VideoFrontmatter { title: string; @@ -17,13 +18,14 @@ export interface VideoFrontmatter { date: string; sitemap: { priority: number; - changefreq: 'daily' | 'weekly' | 'monthly' | 'yealry'; + changefreq: 'daily' | 'weekly' | 'monthly' | 'yearly'; }; tags: string[]; } export type VideoFileType = MarkdownFileType & { id: string; + author: AuthorFileType; }; /** @@ -43,12 +45,9 @@ function videoPathToId(filePath: string): string { * @returns Promisifed video files */ export async function getAllVideos(): Promise { - const videos = await import.meta.glob( - '/src/data/videos/*.md', - { - eager: true, - } - ); + const videos = import.meta.glob('/src/data/videos/*.md', { + eager: true, + }); const videoFiles = Object.values(videos); const enrichedVideos = videoFiles.map((videoFile) => ({ @@ -59,6 +58,6 @@ export async function getAllVideos(): Promise { return enrichedVideos.sort( (a, b) => new Date(b.frontmatter.date).valueOf() - - new Date(a.frontmatter.date).valueOf() + new Date(a.frontmatter.date).valueOf(), ); } diff --git a/src/pages/authors/[authorId].astro b/src/pages/authors/[authorId].astro new file mode 100644 index 000000000..61097093a --- /dev/null +++ b/src/pages/authors/[authorId].astro @@ -0,0 +1,110 @@ +--- +import BaseLayout from '../../layouts/BaseLayout.astro'; +import AstroIcon from '../../components/AstroIcon.astro'; +import { getGuidesByAuthor } from '../../lib/guide'; +import { getAllVideos } from '../../lib/video'; +import GuideListItem from '../../components/GuideListItem.astro'; +import { getAuthorById, getAuthorIds } from '../../lib/author'; + +interface Params extends Record {} + +export async function getStaticPaths() { + const authorIds = await getAuthorIds(); + + return authorIds.map((authorId) => ({ + params: { authorId }, + })); +} + +const { authorId } = Astro.params; + +const author = await getAuthorById(authorId); + +const guides = await getGuidesByAuthor(authorId); +const videos = await getAllVideos(); +--- + + +
+
+
+
+

{author.frontmatter.name}

+
+ +
+ +
+
+ { + author.frontmatter.social?.github && ( + + + + ) + } + { + author.frontmatter.social.twitter && ( + + + + ) + } + { + author.frontmatter.social.linkedin && ( + + + + ) + } + { + author.frontmatter.social.website && ( + + + + ) + } +
+
+
+ +
+
+
+ {guides.map((guide) => )} +
+
+