Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a way for extending themes to add layouts #2547

Closed
4 tasks done
aentwist opened this issue Jun 25, 2023 · 1 comment
Closed
4 tasks done

Provide a way for extending themes to add layouts #2547

aentwist opened this issue Jun 25, 2023 · 1 comment
Labels
enhancement New feature or request theme Related to the theme

Comments

@aentwist
Copy link

Is your feature request related to a problem? Please describe.

For my theme which extends the default theme, I want to have a contact page with a custom layout.

Describe the solution you'd like

Users
---
layout: contact
---

# Contact

content
Devs

Effectively add custom blocks here

<VPHome v-else-if="frontmatter.layout === 'home'">
<template #home-hero-before><slot name="home-hero-before" /></template>
<template #home-hero-info><slot name="home-hero-info" /></template>
<template #home-hero-image><slot name="home-hero-image" /></template>
<template #home-hero-after><slot name="home-hero-after" /></template>
<template #home-features-before><slot name="home-features-before" /></template>
<template #home-features-after><slot name="home-features-after" /></template>
</VPHome>
<VPDoc v-else>
<template #doc-top><slot name="doc-top" /></template>
<template #doc-bottom><slot name="doc-bottom" /></template>
<template #doc-footer-before><slot name="doc-footer-before" /></template>
<template #doc-before><slot name="doc-before" /></template>
<template #doc-after><slot name="doc-after" /></template>
<template #aside-top><slot name="aside-top" /></template>
<template #aside-outline-before><slot name="aside-outline-before" /></template>
<template #aside-outline-after><slot name="aside-outline-after" /></template>
<template #aside-ads-before><slot name="aside-ads-before" /></template>
<template #aside-ads-after><slot name="aside-ads-after" /></template>
<template #aside-bottom><slot name="aside-bottom" /></template>
</VPDoc>

For example

<MyContact v-if="frontmatter.layout === 'contact'">
  <!-- define slots for this layout, if any -->
</MyContact>

This needs a lot of consideration, but I might propose something like

import Contact from "./components/MyContact.vue";

export default <Theme>{
  // ...
  customLayouts: {
    contact: Contact,
  },
};

Then in VPContent,

<component v-else-if="customLayouts[frontmatter.layout]" :is="customLayouts[frontmatter.layout]"></component>

Describe alternatives you've considered

  • Override the VPContent component - very fragile coupling
  • Use the page layout with a custom frontmatter key under which additional layouts can be specified - cannot control Content, workaround hack
Users
---
layout: page
type: contact
---

# Contact

content
Devs

MyLayout.vue

<template>
  <Layout>
    <template v-if="frontmatter.type === 'about'" #page-top>
      about page top
    </template>
    <template v-if="frontmatter.type === 'about'" #page-bottom>
      about page bottom
    </template>

    <template v-if="frontmatter.type === 'contact'" #page-top>
      contact page top
    </template>
    <template v-if="frontmatter.type === 'contact'" #page-bottom>
      contact page bottom
    </template>
  </Layout>
</template>
An element cannot have multiple '<template>' elements which are distributed to the same slot.eslint[vue/valid-v-slot](https://eslint.vuejs.org/rules/valid-v-slot.html)

OR

<template>
  <Layout>
    <template #page-top>
      <template v-if="frontmatter.type === 'about'">
        about page top
      </template>
      <template v-if="frontmatter.type === 'contact'">
        contact page top
      </template>
    </template>

    <template #page-bottom>
      <template v-if="frontmatter.type === 'about'">
        about page bottom
      </template>
      <template v-if="frontmatter.type === 'contact'">
        contact page bottom
      </template>
    </template>
  </Layout>
</template>

(Terrible maintainability)

Additional context

No response

Validations

@bojanrajh
Copy link
Contributor

bojanrajh commented Jul 11, 2023

@brc-dd Could something like this work?

Change <VPDoc v-else> into <component v-else :is="frontmatter.layout || 'VPDoc'">.

@brc-dd brc-dd added enhancement New feature or request theme Related to the theme labels Aug 6, 2023
@brc-dd brc-dd closed this as completed in f4a5c43 Aug 6, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request theme Related to the theme
Projects
None yet
Development

No branches or pull requests

3 participants