瀏覽代碼

Adds meta tags

Alicia Sykes 2 年之前
父節點
當前提交
714a528bce
共有 4 個文件被更改,包括 67 次插入19 次删除
  1. 15 0
      src/routes/+layout.svelte
  2. 9 4
      src/routes/+page.svelte
  3. 7 5
      src/routes/[slug]/+page.server.ts
  4. 36 10
      src/routes/[slug]/+page.svelte

+ 15 - 0
src/routes/+layout.svelte

@@ -26,6 +26,21 @@
   }
 </script>
 
+<svelte:head>
+  <title>Portainer Templates</title>
+  <meta name="description" content="A community-driven library of 1-click self-hosted apps" />
+  <meta property="og:title" content="Portainer Templates" />
+  <meta property="og:description" content="A community-driven library of 1-click self-hosted apps" />
+  <meta property="og:type" content="website" />
+  <meta property="og:url" content="{import.meta.env.VITE_PUBLIC_BASE_URL}/" />
+  <meta property="og:image" content="{import.meta.env.VITE_PUBLIC_BASE_URL}/banner.png" />
+  <meta name="twitter:card" content="summary_large_image" />
+  <meta name="twitter:title" content="Portainer Templates" />
+  <meta name="twitter:description" content="A community-driven library of 1-click self-hosted apps" />
+  <meta name="twitter:image" content="{import.meta.env.VITE_PUBLIC_BASE_URL}/banner.png" />
+  <link rel="canonical" href="{import.meta.env.VITE_PUBLIC_BASE_URL}" />
+</svelte:head>
+
 {#if showNav}
   <Header />
 {/if}

+ 9 - 4
src/routes/+page.svelte

@@ -1,4 +1,5 @@
 <script lang="ts">
+  import { page } from '$app/stores'
 
   import Hero from '$lib/Hero.svelte';
   import ListFilter from '$lib/ListFilter.svelte';
@@ -11,20 +12,24 @@
 
   export let data;
 
+
+
+  const preSelectedCategories = $page.url.searchParams.get('categories');
+
   let searchTerm = '';
 
-  let showCategories = false;
+  let selectedCategories: string[] = preSelectedCategories?.split(',') || [];
 
-  let selectedCategories: string[] = [];
+  let showCategories = !!preSelectedCategories || false;
   
   $: filteredTemplates = data.templates.filter((template: Template) => {
     const compareStr = (str1: string, str2: string) =>
       (str1 || '').toLowerCase().includes(str2.toLowerCase());
 
     if (selectedCategories.length) {
-      const templateCategories = template.categories || [];
+      const templateCategories = (template.categories || []).map((c) => c.toLowerCase());
       const hasSelectedCategory = selectedCategories.some((cat) =>
-        templateCategories.includes(cat)
+        templateCategories.includes(cat.toLocaleLowerCase())
       );
       if (!hasSelectedCategory) return false;
     }

+ 7 - 5
src/routes/[slug]/+page.server.ts

@@ -53,10 +53,13 @@ const getServices = async (template): Promise<Service[]> => {
             container: vol.split(':')[1],
           })),
           restart_policy: serviceData.restart,
-          env: Object.keys(serviceData.environment || {}).map((envName) => ({
-            name: envName,
-            value: serviceData.environment[envName],
-          })),
+          env: Object.keys(serviceData.environment || {}).map((envName) => {
+            if (typeof envName === 'string') {
+              const nowItsArray = serviceData.environment[envName].split('=') || [];
+              return { name: nowItsArray[0] || '',  value: nowItsArray[1] || '' }
+            }
+            return { name: envName, value: serviceData.environment[envName] }
+          }),
         });
       });
       return someServices;
@@ -80,7 +83,6 @@ const returnResults = async (templates, templateSlug) => {
   // If only 1 service, merge it with the template
   if (services.length === 1) {
     template = {...template, ...services[0]};
-    services = [];
   } else if (services.length > 1) {
     // If made up from multiple services, fetch Docker info for each image
     services = await Promise.all(

+ 36 - 10
src/routes/[slug]/+page.svelte

@@ -14,7 +14,6 @@
   const template = $page.data.template as Template;
   const dockerStats = $page.data.dockerStats as DockerHubResponse;
   const services = $page.data.services as Service[];
-  const serviceDockerStats = $page.data.serviceDockerStats as DockerHubResponse[] || null;
 
   const makeMultiDoc = (services: Service[]) => {
     return services.map((s) => {
@@ -27,8 +26,25 @@
     }).filter((thingy) => thingy !== null);
   };
 
+  const makeMetaDescription = () => {
+    return `Installation guide for ${template.title}, using Portainer, Docker Run or Docker-Compose. `
+    +`Portainer-Templates is a community driven repository of Portainer Templates for Self-Hosted apps. \n`
+    +`${template.description}`;
+  }
+
 </script>
 
+<svelte:head>
+  <title>{template.title} | Portainer Templates</title>
+  <meta name="description" content={makeMetaDescription()} />
+  <meta property="og:title" content="{template.title} | Portainer Templates" />
+  <meta property="og:description" content={makeMetaDescription()} />
+  <meta property="og:url" content="{import.meta.env.VITE_PUBLIC_BASE_URL}/{urlSlug}" />
+  <meta name="twitter:title" content="{template.title} | Portainer Templates" />
+  <meta name="twitter:description" content={makeMetaDescription()} />
+  <link rel="canonical" href="{import.meta.env.VITE_PUBLIC_BASE_URL}/{urlSlug}" />
+</svelte:head>
+
 {#if template}
   <section class="summary-section">
     <h1>
@@ -38,7 +54,7 @@
     {#if template.categories || template.category }
       <p class="tags">
         {#each (template.categories || template.category || []) as tag}
-          <span>{tag}</span>
+          <a href="/?categories={tag}"><span>{tag}</span></a>
         {/each}
       </p>
     {/if}
@@ -56,7 +72,7 @@
   </section>
 
   {#await services then returnedServices}
-  {#if returnedServices && returnedServices.length > 0}
+  {#if returnedServices && returnedServices.length > 1}
     <section class="service-section">
       <h2>Services</h2>
       <div class="service-list">
@@ -115,14 +131,24 @@
     .tags {
       display: flex;
       margin: 0;
-      span {
-        &:before {
-          content: '#';
-          opacity: 0.5;
+      gap: 0.5rem;
+      a {
+        color: var(--foreground);
+        text-decoration: none;
+        transition: all 0.2s ease-in-out;
+        span {
+          &:before {
+            content: '#';
+            opacity: 0.5;
+          }
+          &:not(:last-child)::after {
+            content: ',';
+            margin-right: 0.5rem;
+          }
         }
-        &:not(:last-child)::after {
-          content: ',';
-          margin-right: 0.5rem;
+        &:hover {
+          color: var(--accent);
+          transform: scale(1.08);
         }
       }
     }