diff --git a/src/components/PageContent/index.tsx b/src/components/PageContent/index.tsx
index 4cc4b85..29246d0 100644
--- a/src/components/PageContent/index.tsx
+++ b/src/components/PageContent/index.tsx
@@ -1,8 +1,8 @@
-import React, { FC, Fragment } from "react"
+import React, { FC } from "react"
-import { ITocItem } from "../../types"
-import { humanize } from "../../utils"
+import { IExternalResource, ITocItem } from "../../types"
import { Container } from "../Container"
+import { PageSidebarLink } from "../PageSidebarLink"
import { Toc } from "../Toc"
import * as SC from "./styles"
@@ -10,37 +10,7 @@ interface IPageContentProps {
content: JSX.Element
toc?: ITocItem[]
recommendedReading?: string[]
- externalResources?: string[]
-}
-
-function ExtraLink({
- item,
- external = false,
-}: {
- item: string
- external?: boolean
-}) {
- const Inner = ({ text }: { text: string }) => (
-
- {text}
-
- )
-
- if (external) {
- return (
-
-
-
- )
- }
-
- const [internalText] = item.split("/").slice(-1)
-
- return (
-
-
-
- )
+ externalResources?: IExternalResource[]
}
export const PageContent: FC = ({
@@ -67,7 +37,7 @@ export const PageContent: FC = ({
Recommended reading
{recommendedReading.map(item => {
- return
+ return
})}
)}
@@ -76,7 +46,7 @@ export const PageContent: FC = ({
External Resources
{externalResources.map(item => {
- return
+ return
})}
)}
diff --git a/src/components/PageContent/styles.tsx b/src/components/PageContent/styles.tsx
index 31922a7..290e4ad 100644
--- a/src/components/PageContent/styles.tsx
+++ b/src/components/PageContent/styles.tsx
@@ -1,5 +1,4 @@
-import styled, { css } from "styled-components"
-import { Link } from "gatsby"
+import styled from "styled-components"
import fontFamily from "../../design/typography"
import { darken } from "polished"
@@ -53,6 +52,8 @@ export const SidebarHeader = styled.div`
const ExtraLinks = styled.div`
margin-top: 32px;
+ display: flex;
+ flex-direction: column;
&:first-child {
margin-top: 0;
@@ -62,53 +63,3 @@ const ExtraLinks = styled.div`
export const RecommendedReading = styled(ExtraLinks)``
export const ExternalResources = styled(ExtraLinks)``
-
-const extraLink = css`
- display: flex;
- align-items: center;
- color: ${props => (props.theme.name === "dark" ? "#f9f9f9" : "#172129")};
- cursor: pointer;
- text-decoration: none;
-
- & + & {
- margin-top: 8px;
- }
-
- &:hover {
- background: linear-gradient(92.97deg, #feaf6d 0%, #ff70a5 100%);
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
-
- svg {
- width: 14px;
- flex: 0 0 14px;
- transform: rotate(90deg);
- margin-left: 6px;
- }
-
- svg path {
- fill: ${props => (props.theme.name === "dark" ? "#f9f9f9" : "#172129")};
- }
-`
-
-export const ExtraLinkInternal = styled(Link)`
- ${extraLink};
-`
-
-export const ExtraLinkExternal = styled.a`
- ${extraLink};
-`
-
-export const ExtraLinkText = styled.div`
- word-break: break-word;
-
- &::after {
- content: "";
- display: block;
- width: 100%;
- height: 2px;
- background: linear-gradient(92.97deg, #feaf6d 0%, #ff70a5 100%);
- }
-`
diff --git a/src/components/PageSidebarLink/index.tsx b/src/components/PageSidebarLink/index.tsx
new file mode 100644
index 0000000..ad49c3e
--- /dev/null
+++ b/src/components/PageSidebarLink/index.tsx
@@ -0,0 +1,37 @@
+import React, { FC } from "react"
+
+import { humanize } from "../../utils"
+import * as SC from "./styles"
+
+interface IPageSidebarLinkProps {
+ href: string
+ text?: string
+ external?: boolean
+ type?: "internal" | "external" | "anchor"
+}
+
+export const PageSidebarLink: FC = ({
+ href,
+ text,
+ type = "internal",
+}) => {
+ if (type === "anchor") {
+ return {text}
+ }
+
+ if (type === "external") {
+ return (
+
+ {text}
+
+ )
+ }
+
+ const [internalText] = href.split("/").slice(-1)
+
+ return (
+
+ {text || humanize(internalText)}
+
+ )
+}
diff --git a/src/components/PageSidebarLink/styles.tsx b/src/components/PageSidebarLink/styles.tsx
new file mode 100644
index 0000000..5497ca6
--- /dev/null
+++ b/src/components/PageSidebarLink/styles.tsx
@@ -0,0 +1,26 @@
+import { AnchorLink } from "gatsby-plugin-anchor-links"
+import styled, { css } from "styled-components"
+import { Link } from "gatsby"
+
+const extraLink = css`
+ color: ${props => props.theme.main.foreground};
+ text-decoration: none;
+ word-break: break-word;
+
+ &:hover,
+ &:focus {
+ text-decoration: underline;
+ }
+`
+
+export const Anchor = styled(AnchorLink)`
+ ${extraLink};
+`
+
+export const Internal = styled(Link)`
+ ${extraLink};
+`
+
+export const External = styled.a`
+ ${extraLink};
+`
diff --git a/src/components/Toc/index.tsx b/src/components/Toc/index.tsx
index 06350f5..aea1c17 100644
--- a/src/components/Toc/index.tsx
+++ b/src/components/Toc/index.tsx
@@ -1,4 +1,5 @@
import React, { FC } from "react"
+import { PageSidebarLink } from "../PageSidebarLink"
import { ITocItem } from "../../types"
import * as SC from "./styles"
@@ -40,7 +41,7 @@ export const Toc: FC = ({ header, items }) => {
return (
{prefix}
- {title}
+
)
})}
diff --git a/src/components/Toc/styles.tsx b/src/components/Toc/styles.tsx
index d2cb591..69ea637 100644
--- a/src/components/Toc/styles.tsx
+++ b/src/components/Toc/styles.tsx
@@ -1,4 +1,3 @@
-import { AnchorLink } from "gatsby-plugin-anchor-links"
import styled from "styled-components"
export const TocWrapper = styled.div`
@@ -18,13 +17,3 @@ export const TocItem = styled.div`
margin-top: 8px;
}
`
-
-export const TocLink = styled(AnchorLink)`
- color: ${props => props.theme.main.foreground};
- text-decoration: none;
-
- &:hover,
- &:focus {
- text-decoration: underline;
- }
-`
diff --git a/src/content/resources/bot-development/bot-deployment-with-heroku.md b/src/content/resources/bot-development/bot-deployment-with-heroku.md
index 66c5daf..b4a1c4d 100644
--- a/src/content/resources/bot-development/bot-deployment-with-heroku.md
+++ b/src/content/resources/bot-development/bot-deployment-with-heroku.md
@@ -4,8 +4,10 @@ authors:
created_at: "2020/04/22"
title: "Deploying discord bots written in Kotlin to Heroku"
external_resources:
- - "https://devcenter.heroku.com/articles/getting-started-with-java#introduction"
- - "https://github.com/heroku/java-sample"
+ - text: Getting Started on Heroku with Java
+ href: "https://devcenter.heroku.com/articles/getting-started-with-java#introduction"
+ - text: Java Sample (on GitHub)
+ href: "https://github.com/heroku/java-sample"
---
Over my time in TPH, I have noticed that a common woe aspiring bot developers have is that they are unable to host
diff --git a/src/content/resources/java/streams.md b/src/content/resources/java/streams.md
index 6d6f58c..08d80aa 100644
--- a/src/content/resources/java/streams.md
+++ b/src/content/resources/java/streams.md
@@ -4,7 +4,8 @@ authors:
title: "An introduction to Streams"
created_at: 2019/12/15
external_resources:
- - https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/
+ - text: Java8 Stream Tutorial
+ href: https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/
---
## An introduction to Streams
diff --git a/src/content/resources/javascript/spread-operator.md b/src/content/resources/javascript/spread-operator.md
index 8057081..4a99941 100644
--- a/src/content/resources/javascript/spread-operator.md
+++ b/src/content/resources/javascript/spread-operator.md
@@ -4,9 +4,12 @@ authors:
title: "Spread operator"
created_at: 2019/08/10
external_resources:
- - "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"
- - "https://javascript.info/rest-parameters-spread-operator"
- - "https://www.freecodecamp.org/news/spread-operator-and-rest-parameter-in-javascript-es6-4416a9f47e5e/"
+ - text: MDN Spread Operator
+ href: "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"
+ - text: Javascript.info Spread/rest
+ href: "https://javascript.info/rest-parameters-spread-operator"
+ - text: Freecodecamp.org Spread/rest
+ href: "https://www.freecodecamp.org/news/spread-operator-and-rest-parameter-in-javascript-es6-4416a9f47e5e/"
---
# An overview of the spread operator
diff --git a/src/content/resources/kotlin/native/creating-c-bindings.md b/src/content/resources/kotlin/native/creating-c-bindings.md
index dda446c..cb1632b 100644
--- a/src/content/resources/kotlin/native/creating-c-bindings.md
+++ b/src/content/resources/kotlin/native/creating-c-bindings.md
@@ -4,8 +4,10 @@ authors:
created_at: "2019/08/23"
title: "Creating C bindings with Kotlin/Native"
external_resources:
- - "https://kotlinlang.org/docs/reference/native/c_interop.html"
- - "https://github.com/JetBrains/kotlin-native/releases"
+ - text: KotlinLang.org C-interop reference
+ href: "https://kotlinlang.org/docs/reference/native/c_interop.html"
+ - text: Kotlin releases on GitHub
+ href: "https://github.com/JetBrains/kotlin-native/releases"
---
## Interoperability with C
diff --git a/src/content/resources/php/design-patterns/singleton.md b/src/content/resources/php/design-patterns/singleton.md
index b2e12cb..4f41588 100644
--- a/src/content/resources/php/design-patterns/singleton.md
+++ b/src/content/resources/php/design-patterns/singleton.md
@@ -4,14 +4,22 @@ authors:
created_at: "2019/07/27"
title: Singletons
external_resources:
- - https://en.wikipedia.org/wiki/Singleton_pattern
- - https://phpenthusiast.com/blog/the-singleton-design-pattern-in-php
- - https://phptherightway.com/pages/Design-Patterns.html#singleton
- - https://www.php.net/manual/en/language.oop5.static.php
- - https://www.php.net/manual/en/language.oop5.late-static-bindings.php
- - https://en.wikipedia.org/wiki/Static_(keyword)
- - https://en.wikipedia.org/wiki/Null_coalescing_operator
- - https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
+ - text: Wikipedia.org Singleton Pattern
+ href: https://en.wikipedia.org/wiki/Singleton_pattern
+ - text: phpenthusiast.com Singleton Pattern
+ href: https://phpenthusiast.com/blog/the-singleton-design-pattern-in-php
+ - text: phptherightway.com Singleton Pattern
+ href: https://phptherightway.com/pages/Design-Patterns.html#singleton
+ - text: php.net Static Keyword
+ href: https://www.php.net/manual/en/language.oop5.static.php
+ - text: php.net Late Static Bindings
+ href: https://www.php.net/manual/en/language.oop5.late-static-bindings.php
+ - text: Wikipedia.org Static Keyword
+ href: https://en.wikipedia.org/wiki/Static_(keyword)
+ - text: Wikipedia.org Null Coalescing Operator
+ href: https://en.wikipedia.org/wiki/Null_coalescing_operator
+ - text: php.net Null coalescing operator
+ href: https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
---
A singleton is a class which is only instantiated once during runtime. This is done by keeping a static property containing its instance on the singleton class.
diff --git a/src/content/resources/php/pdo/prepared-statements.md b/src/content/resources/php/pdo/prepared-statements.md
index 49facea..afa8330 100644
--- a/src/content/resources/php/pdo/prepared-statements.md
+++ b/src/content/resources/php/pdo/prepared-statements.md
@@ -4,8 +4,10 @@ authors:
created_at: "2019/08/07"
title: Prepared Statements
external_resources:
- - https://www.php.net/manual/en/class.pdostatement.php
- - https://phptherightway.com/#pdo_extension
+ - text: php.net The PDOStatement class
+ href: https://www.php.net/manual/en/class.pdostatement.php
+ - text: phptherightway.com PDO Extension
+ href: https://phptherightway.com/#pdo_extension
---
The PDO driver supports prepared statements. A prepared statement is a template statement with placeholders which can be executed with real values. Prepared Statements are also essential for avoiding SQL-injection attacks.
diff --git a/src/templates/languageHome.tsx b/src/templates/languageHome.tsx
index af4e78e..dff7dd1 100644
--- a/src/templates/languageHome.tsx
+++ b/src/templates/languageHome.tsx
@@ -67,7 +67,10 @@ export const query = graphql`
created_at
title
recommended_reading
- external_resources
+ external_resources {
+ text
+ href
+ }
}
timeToRead
}
diff --git a/src/templates/languagePost.tsx b/src/templates/languagePost.tsx
index 3105044..66cc98f 100644
--- a/src/templates/languagePost.tsx
+++ b/src/templates/languagePost.tsx
@@ -80,7 +80,10 @@ export const query = graphql`
created_at
title
recommended_reading
- external_resources
+ external_resources {
+ text
+ href
+ }
}
timeToRead
}
diff --git a/src/types/index.d.ts b/src/types/index.d.ts
index e82480f..00e034c 100644
--- a/src/types/index.d.ts
+++ b/src/types/index.d.ts
@@ -56,6 +56,11 @@ export interface IAllArchivesQuery extends IAllFilesQuery {
}
}
+export interface IExternalResource {
+ text: string
+ href: string
+}
+
export interface ITocItem {
depth: number
link: string