Git Product home page Git Product logo

Comments (17)

drwpow avatar drwpow commented on May 3, 2024 3

But... maybe the pros outweigh the cons here. @drwpow experimented with this in https://gitlab.com/pikapkg/hosting-experiments/-/merge_requests/3 and I think I talked him out of it, but maybe its worth revisiting.

FWIW I’m still on team “no layout” 😛. I think there were some rough edges in the PR, but when it comes to pagination I think you have to learn how to load .md files anyway. And I liked the consistency of learning how to load .md files and using it consistently everywhere. It ended up being more “top-down“ and “React-like.” I think if we improved that DX it‘d be less mental overhead. But take that 100% as my opinion; I personally just get confused by having .md files be a route.

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024 2

Played around with this a bit tonight: https://github.com/snowpackjs/astro/compare/wip-no-layout?expand=1#diff-5b70b2cf9fac365ce8bd02496d6de5aaf87f7d6815488c80e947d19b6299eb38

  • pages/index.hmx converted
  • layouts/base.hmx converted, split into BaseLayout and BaseHead.

The good:

  • I really like that this takes us back to "a page must always be <html><head>...</head><body>...</body></html>. "It's just HTML!"
  • <BaseHead /> forced me to be more specific about props instead of a general shared context
  • <BaseLayout /> almost forced some "props drilling" from page -> BaseLayout -> Nav component. Not the worst thing in the world (such react, much wow) and then I realized that I could just load that variable directly inside the Nav component and get rid of the issue. But lets go back and make sure that we're good with prop-drilling, or add back the idea of context.
  • I actually pretty much got rid of "context" entirely in this, which was unexpected but kind of exciting. Was inheriting/merging context that just a required construct of having nested layouts? Now I can just set things as direct variables in the page (title and description). The page itself basically acts as the top-level shared context.

The ugly:

  • As a user, I'm confused what to do with <script> and <style> in a page. I'm so used to these being top-level "special" concepts in a component, but to follow that it feels really odd to have a <script> and <style> to live outside of the page<html>. But then if I put them in the <html>, where? Top of the <head>? Now I'm really mixing JS and HTML together and the context shifting feels really offputting. I have an idea that I want to explore here that might help.

from astro.

drwpow avatar drwpow commented on May 3, 2024 1

To clarify: by “no layout” I meant to say I‘m -1 only on loading layouts from frontmatter. Not the entire concept of layouts. I’m in favor of this approach, personally.

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024 1

Opening another can of worms, which should be moved to another issue? Explicity return props and components from the setup function.

Yea, this has become more obviously "weird" in the move away from nested layouts. That's a good thing since I think its always been weird, but lets spin up a separate thread to address.

Introduce an tag which can have a single <script> tag and n number of <style> tags

So what's interesting about <style> is that it actually doesn't have this same <script astro> "where does it go?" problem. <style> tags go in the head! And represent an element that will eventually end up on the page. It still has the "context shifting / content mixing" problem of nesting CSS styles inside of HTML markup, but since it's all about constructing the full HTML output I think it's more clear since that's kind of just how HTML works (plus you may want control over where those styles live in the head?).

If everyones onboard, I'd love to try the --- approach first and then see how it feels as users. Definitely not opposed to <astro><script/><style/></astro> if we still feel like somethings missing afterwards.

from astro.

natemoo-re avatar natemoo-re commented on May 3, 2024

I'm very much in favor of this approach!

At first I started to think about how Markdown pages would declare their Layout component, but now I'm starting to rethink Markdown pages entirely. What if we didn't use Markdown pages as entry points and required all pages to be HMX? In order to render a "Markdown" page, we could have an astro:markdown component? So you could do something like this for inline content.

<script astro>
    import Layout from '../layouts/blog.hmx';
</script>

<Layout>
    <Fragment slot="astro:head">
        <title>My Blog Post</title>
       <link rel="stylesheet" href="/styles/blog.css">
    </Fragment>
    
    <astro:markdown>
      # Hello world!
    </astro:markdown>
</Layout>

This approach would have the added benefit of not requiring Markdown content to be inside of your pages/ directory. What if you want the Markdown to live in a docs/ directory? Or a remote source? Could <astro:markdown> just accept a src attribute? Whenever we introduce dynamic routes and a data-fetching interface, the src could easily by dynamic.

<script astro>
    import Layout from '../layouts/blog.hmx';
</script>

<Layout>
    <Fragment slot="astro:head">
        <title>My Blog Post</title>
       <link rel="stylesheet" href="/styles/blog.css">
    </Fragment>
    
    <astro:markdown src="../docs/hello-world.md" />
</Layout>

from astro.

natemoo-re avatar natemoo-re commented on May 3, 2024

Much of that thinking is inspired by next-mdx-remote, by the way! And astro:markdown doesn't even need to be a special component, we could just expose import Markdown from 'astro/markdown'.

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024

Yea this feels really nice, I that's a great call out that we've moved away from our "it's just HTML" roots.

I think I'm totally sold on the idea of Layouts as components. Slots could be generic too which is really nice for keeping overall number of concepts low.

Also a strong +1 for having a special slot fragment component, and maybe not even supporting "slot=XXX" on any arbitrary component. I like <Template> but agree it's overloaded. Maybe just <SlotContent slot="...">?

Also another strong +1 for having a "no slots boilerplate" flow when its not necessary. Slots are still a new concept to many, and besides the extra boilerplate I think they oddly take us back out of the "its just HTML" world that we want to get back to. I still see a lot of value in just doing this if you can:

<script astro>
  import BlogLayout from '../layouts/blog.hmx';
</script>

<BlogLayout>
  <div>... blog post content here</div>
<BlogLayout>

And then I think the question becomes: does adding to the head mean you need to enter "multi-slot boilerplate mode"? Or, do we still have a special component for adding things to the head, if you don't own the head?

<BlogLayout>
  <div>... blog post content here</div>
<BlogLayout>

<!-- and then, if you wanted to add to head... -->
<astro:head>
  <title>My Blog Post</title>
  <link rel="stylesheet" href="/styles/blog.css">
</astro:head>

I might be thinking too far ahead on this point, though. If we want named slots anyway, lets just build that first and see how it feels. Happy to revisit this later on down the road.

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024

@natemoo-re that's 100% where I want to see us go when we start introducing dynamic route handlers. Basically having something like /pages/docs/[slug].hmx matching all incoming routes, and then looking up files in a docs/ or content/ directory, and then loading it onto the page sort of like you have here.

The problem is that I still see the value in having 1:1 "markdown files : page", since it gives you a super clear way to understand your site structure. "I added this file, and now a new page lives at this URL". It's also easier to build your site, since you have a 1:1 mapping of files to pages.

But... maybe the pros outweigh the cons here. @drwpow experimented with this in https://gitlab.com/pikapkg/hosting-experiments/-/merge_requests/3 and I think I talked him out of it, but maybe its worth revisiting. Especially since it ties into the above, and we may be able to get rid of the layouts concept entirely (and could then push off the named slot support talked about above to a much later stage of development). /cc @matthewp

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024

Okay, so attempting to summarize where we're at as a team: There's interest in an experiment to implement:

  • layouts/ is no longer a concept, no more layout nesting, etc.
  • pages/ is still a thing, but pages are now full HTML.
    • That incudes <html> (maybe) and <head> + <body> (definitely)
  • Pages can still leverage common layout logic, like <BlogLayout>
    • Can just support a single slot for now
    • future: A <SlotContent slot="..."> component that makes it easier to work with multiple, named slots.

And then the big question still remaining is: How do markdown files relate to pages/routes?

  • Option: Keep the current pages/*.md, and keep the current idea of frontmatter layout: '../components/BlogLayout.hmx'? (Freds personal pref: unclear, but leaning -1 if this is just stretching an old idea too far now)
  • Option: Zero top-level markdown files, and instead <astro:markdown>...</> inside of HMX? (Freds personal pref: -1, sometimes devs just wanna write a .md file, worried this would be too alienating to be the only way to do it, but I love the concept of a <Markdown> component now being possible!).
  • Option: Go full into the world of dynamic page loaders: A new top-level content/*.md directory and support for [slug].hmx pages that can load data dynamically out of that content directory. (Freds personal pref: leaning +1 now, I think my first impression of "yea but I can't understand the exact pages & URL scheme that we're building just by looking at the pages/ directory structure" doesn't outweigh the pros here.)

Anything else that I'm missing in either section? Thoughts of the above?

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024

Okay yall, keep an open mind with me of this one: a77a2e6

---
  import Menu from '../components/Menu.hmx';
  import Hero from '../components/Hero.hmx';
  import BaseHead from '../layouts/BaseHead.hmx';
  import BaseLayout from '../layouts/BaseLayout.hmx';

  let title = 'Snowpack';
  let description = 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.';
  export function setup({ context }) {
    return {};
  }
---
<html>
  <head>
    <BaseHead title={title} description={description} />

At first I was skeptical, but then I realized that it solves some really core/essential problems for us including the big one mentioned in the post above. And now that I've spent some time with it I'm REALLY digging it.

Problems solved

  • <script astro> - unlike every other element you write, this one isn't actually an element on the page. <script> would be, but then adding the astro attribute turns it into something special that runs server-side/build-time. This is really unique and no other elements/attributes have special rules anything like this.
  • What if I put 2 <script astro> components on the page? (we have to error). What if 0? (okay). What if I put <script astro> somewhere nested inside the markup? (error? okay? not sure).
  • I think the root of the issues outlined above is that you're mixing component markup (HTML) and component setup/configuration/imports (JS) together. As a user I'd really want to think of setup as different from markup, which is why having setup inside markup feels so odd.
  • The main issue that kicked this off: Where does <script astro> live? In components it's a top-level thing, but in pages there's no good place for it (see "the ugly" above). This is the biggest issue worth solving imo.
  • Bonus: Frontmatter is already a concept/syntax that devs are familiar with (not true with <script astro>).

@natemoo-re I know that we can parse this easy enough into the same exact parse result that we use today, but let me know if this is somehow very tricky in VSCode world.

from astro.

matthewp avatar matthewp commented on May 3, 2024

Well I'm glad people have run with this idea 😀. For clarity I'm personally not against layouts at all. I'm not even against a layout prop being returned from the setup script (or in frontmatter in markdown). What I was trying to hit at in this thread is that the primitive of layouts should be components. A special "layout" concept in markdown/etc. can be sugar on top of ordinary component usage. So this thread was intended to be an alternative idea to how they are implemented more so than questioning their overall usefulness.

And I definitely thinking markdown files as pages is a good thing, and pretty much expected if we are going to try to keep in the blog space (I think we want to). We just need to decide what a markdown page compiles to so that we can tell a layout author what slot names exist, etc.

from astro.

matthewp avatar matthewp commented on May 3, 2024

@FredKSchott

Option: Keep the current pages/*.md,

I like this option as well, I don't think we should go too far with this idea. Markdown pages are still a special-case, we just need to define what they get translated into and document how to write a Layout component for them.

from astro.

matthewp avatar matthewp commented on May 3, 2024

@FredKSchott re frontmatter setup script ->

That's pretty interesting! You're right that moving to a full-page structure makes it not obvious where to stick the setup script. I think I can grow to like the frontmatter approach. It's similar to 11ty which allows frontmatter in nunjunks templates at the top like that. I can see a scenario were we might also support non-JavaScript frontmatter, maybe yaml instead (which is just sugar for what you wrote).

I wonder if the larger revelation here is that you want some separation between the template part of the HMX and the setup part. Previously we had discussed ideas of having <import>, <data>, etc. type of elements that would be sugar for a setup script. Is that still possible within this frontmatter idea? Does it matter if not?

Here's another idea. I don't necessarily like it better, just throwing it out there. If the discovery is having distance between the setup and the template, what about revisiting the <astro> element idea you had mentioned previously, and doing something like this:

<astro>
  <import BlogLayout from="../components/BlogLayout.hmx">

  <script> // No need for astro/setup attributes, this is scoped to setup time.
    export default {
       title: 'My Blog'
    }
  </script>
</astro>


<html lang="en">
  <head> .... <head>
  <body>
    <h1>{title}</h1>
  </body>
</html>

from astro.

natemoo-re avatar natemoo-re commented on May 3, 2024

I really like that concept @FredKSchott! I think having a universal setup area of the page makes the line between the server code and what will actually be included on the page very clear.

At the risk of getting lost in more bikeshedding, but here's a combo between @matthewp's suggestion and @FredKSchott's suggestion. Explanation below, but I think it hits a good middle ground. This format could also carry over to Markdown pages as well, if we go that route, since Markdown can contain any HTML.

<astro>
  <script>
    import BaseHead from '../component/BaseHead.hmx';
   
   /* I'm considering a separate issue for this part! So consider this hand-wavey */
    export function setup({ context }) {
      const title = 'Snowpack';
      const description = 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.';

      return {
        props: { title, description },
        components: { BaseHead }
     };
    }
  </script>
  
  <style lang="scss"> ...  </style>
<astro>

<html lang="en">
  <head>
        <BaseHead title={title} description={description} />
  </head>
  <body>
    <h1>{title}</h1>
  </body>
</html>

What I changed:

  • Introduce an <astro> tag which can have a single <script> tag and n number of <style> tags. This keeps everything "just" HTML without introducing new syntax like import or data.
  • Opening another can of worms, which should be moved to another issue? Explicity return props and components from the setup function. Makes it more clear what is locally scoped to the script and what is exposed to the page. Also thought about export const components = {} but maybe there are different components based on the setup context?

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024

Okay, played around a bit more with this and it definitely changes things, I think for the better. Here's where I'm at: https://github.com/snowpackjs/astro/pull/new/wip-no-layout-2 (VERY WIP, different pages are in different states of transition).

  • No implementation yet, still just playing with the user interface
  • Super happy with all pages being full HTML (<html><head>...). No layout nesting definitely encourages composition with components more, which is exactly what we want to encourage to build a healthy component ecosystem.
  • I'd say I'm like 95% happy with <style> being inside the <head> on pages. The only thing giving me pause is that the pages without styles (ex: pages/news.hmx) feel so much cleaner than the ones with styles (ex: pages/plugins.hmx). Maybe that would be true regardless of where the style lived? Maybe that will encourage users to use components more, and do less styling in pages?
  • Layout nesting is gone, but layouts DO still exist for markdown pages. The current direction of that branch is:
    • Pages are full HTML pages now, no more layouts or nesting allowed.
    • Markdown can still declare a layout though, but the concept of "layouts" is now different. Instead, its more like a page (ex: must return full HTML) that's detached from the file based router, and can be applied to any markdown file arbitrarily. Still not fully fleshed out, but it feels like an interesting & promising direction. You can see it most developed in layouts/content.hmx.
  • Speaking of layouts/content.hmx: by getting rid of layout nesting, we got rid of the idea of context passing. This is finally forcing us to address how props work in pages. layouts/content.hmx contains a few experiments (commented as "Attempt 1" - "Attempt 4") on an API for this, curious to hear thoughts. Feel free to play around with your own ideas here as well!

from astro.

matthewp avatar matthewp commented on May 3, 2024

@FredKSchott I've rebased your branch against the hmx->astro conversion branch and pushed to here: https://github.com/snowpackjs/astro/compare/wip-no-layout-3?expand=1

from astro.

FredKSchott avatar FredKSchott commented on May 3, 2024

Okay, I think this has been resolved with #24 merging. @matthewp @natemoo-re feel free to re-open if there's any part of this still unaddressed (or: spin up a new, more focused issue)

from astro.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.