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

View Render Manager #59

Open
joshmanders opened this issue Mar 11, 2024 · 0 comments
Open

View Render Manager #59

joshmanders opened this issue Mar 11, 2024 · 0 comments
Labels
component:view Pertains to the kubit/view component status:exploring This request is being explored for inclusion type:feature New feature or request

Comments

@joshmanders
Copy link
Member

Right now the view component just supports Edge templates, but we want to abstract it into a manager pattern to support other rendering methods.

This is because Kubit being a traditional MVC backend framework written in JavaScript/TypeScript we're in a unique position to support other view layer renderers such as a React or Vue or even Svelte renderer allowing us to bridge the backend and frontend in truly cohesive ways that neither the modern JavaScript based frontend nor traditional backend frameworks ever fathomed.

First we'll add support for using Vue Single File Components (SFC) as a template renderer to return the string contents directly to the browser, but ultimately the end goal is to support full SSR and client side rehydration of modern frameworks like Nuxt, Remix, and Astro, utilizing the Astro Island architecture for client rehydration by using the defer keyword on a <script setup> tag.

So take the following example code

resources/views/components/Greeter.vue:

<script setup defer lang="ts">
import { ref, onMounted } from 'vue'

const { name = 'World' } = defineProps<{ name?: string }>();

onMounted(() => {
  setTimeout(() => ref.value.innerText = `I'm Batman!`, 1000)
});
</script>

<template>
<h1 ref="greeter">Hello, {{ name }}</h1>
</template>

<style scoped>
.h1 { color: red }
</style>

Then you had this page view

resources/views/pages/home.vue:

<script setup lang="ts">
import Greeter from '../components/Greeter';

const { name } = defineProps<{ name: string }>();
</script>

<template>
  <Greeter :name="name" />
</template>

And you called it in your controller or route handler like so

return view.render('pages/home', { name: 'Josh' });

What would happen here is we would detect that the view home maps to resources/views/pages/home.vue and specifically see the file extension is .vue and it would then render this view using the Vue Renderer. So that would render the home.vue page, which would see that it imports Greeter component. Render the static html string server side, and generate a manifest to load what JavaScript in the browser because the <script startup defer> in the Greeter would tell the Renderer that it has client interactivity and thus needs to inject the necessary JavaScript for that component to hydrate and render client side, which after 1 second would change the contents from "Hello, Josh" to "I'm Batman!".

@joshmanders joshmanders added type:feature New feature or request component:view Pertains to the kubit/view component status:exploring This request is being explored for inclusion labels Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component:view Pertains to the kubit/view component status:exploring This request is being explored for inclusion type:feature New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant