Skip to content

Instantly share code, notes, and snippets.

@connor-davis
Last active December 26, 2022 10:33
Show Gist options
  • Save connor-davis/f77c8ac89fefbb50f4ce8e25be53d222 to your computer and use it in GitHub Desktop.
Save connor-davis/f77c8ac89fefbb50f4ce8e25be53d222 to your computer and use it in GitHub Desktop.
This gist displays how I am working with the strapi cms to dynamically render pages on the frontend.
import { Link, Route, Routes } from "@solidjs/router";
import HeaderImage from "./assets/header.jpg";
import LogoImage from "./assets/logo.jpg";
import axios from "axios";
import { createStore } from "solid-js/store";
import { onMount } from "solid-js";
const PageTextToHtml = ({ content }) => {
const parser = new DOMParser(); // Create a new DOMParser instance.
const doc = parser.parseFromString(
content, // Convert the text/html content to html and give it to the parser to convert it to an html element.
"text/html"
);
return doc.body; // Return the body html element.
};
function App() {
// Create a navbar pages store object that will have the pages
// created in the backend dynamically visible including if they
// are dropdown items.
const [navbarPages, setNavbarPages] = createStore([], {
name: "navbar-pages",
});
// Create the pages store that will store all pages that the
// router needs to show.
const [pages, setPages] = createStore([], {
name: "pages-list",
});
onMount(() => {
axios
.get("http://192.168.1.133:1337/api/pages?populate=*")
.then((response) => {
setNavbarPages([
...response.data.data.map((page) => { // Map the pages data that the backend returns in the response.
return page.attributes.IsDropDown // Check if the page must be a dropdown item.
? { // If it is.
name: page.attributes.name,
slug: page.attributes.slug,
isDropdown: page.attributes.IsDropDown,
dropdownPages: [
...page.attributes.page_contents.data.map( // Map the pages that are related to the page.
(page_content) => {
return {
name: page_content.attributes.title,
slug: page_content.attributes.slug,
};
}
),
],
}
: { // If it isn't.
name: page.attributes.name,
slug: page.attributes.slug,
isDropdown: page.attributes.IsDropDown,
};
}),
]);
response.data.data.map((page) => { // Map the pages data returned in the response.
if (!page.attributes.IsDropDown) { // If the page isn't a dropdown item.
const single = page.attributes.page_contents.data[0]; // Get the page as a single object.
setPages([ // Add it to the pages store.
...pages,
{
slug: single.attributes.slug,
content: single.attributes.content,
},
]);
} else {
setPages([ // Add all the pages related to the page to the pages store.
...pages,
...page.attributes.page_contents.data.map((single) => {
return {
slug: single.attributes.slug,
content: single.attributes.content,
};
}),
]);
}
});
});
});
return (
<div class="flex flex-col w-screen h-screen overflow-y-auto overflow-x-hidden">
<div class="flex flex-col w-full h-auto">
<div class="flex w-full h-auto justify-center">
<img src={LogoImage} />
<img src={HeaderImage} />
</div>
<div class="flex w-full h-auto justify-center text-white bg-gray-800">
{navbarPages.map((page) => (
<Link
href={page.slug}
class={`${page.isDropdown ? "group relative" : ""}`}
>
<p class="p-2 hover:text-lime-100 hover:bg-gray-700">
{page.name}
</p>
{page.isDropdown && (
<div class="absolute hidden group-hover:flex group-hover:flex-col mt-auto w-64 h-auto p-2 bg-gray-800">
{page.dropdownPages.map((droplet) => (
<Link
href={droplet.slug}
class="p-2 hover:text-lime-100 hover:bg-gray-700 shrink-0"
>
{droplet.name}
</Link>
))}
</div>
)}
</Link>
))}
</div>
</div>
<Routes>
{pages.map((page) => (
<Route
path={page.slug}
element={
<div class="flex flex-col w-full h-full bg-lime-100">
<div class="w-full prose prose-green dark:prose-invert max-w-none m-0 prose-img:w-full prose-img:m-0 prose-p:m-0 prose-h1:m-0 p-5 prose-a:text-orange-600 dark:prose-a:text-orang-600 marker:text-orange-600 prose-h1:text-orange-600 dark:prose-h:text-green-600 dark:bg-gray-900 rounded-md animate-fade-in duration-50 ease-in-out px-5 md:px-96 bg-lime-100">
<PageTextToHtml content={page.content} />
</div>
</div>
}
/>
))}
</Routes>
</div>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment