amberframework / amber

A Crystal web framework that makes building applications fast, simple, and enjoyable. Get started with quick prototyping, less bugs, and blazing fast performance.
https://amberframework.org
MIT License
2.57k stars 204 forks source link

Render partial deep views #696

Open bigforcegun opened 6 years ago

bigforcegun commented 6 years ago

Description

Just unusual behavior with render partials and views in deep subfolders - we need to specify full path from project root

Steps to Reproduce

  1. Just create some partials like this

    src/views/shared/
    ├── deep
    │   └── _menu.html.slang
    └── _menu.html.slang
  2. place into view == render(partial: "shared/_menu.html.slang")

all works fine

  1. place into view == render(partial: "shared/deep/_menu.html.slang")

we have error Slang template: shared/deep/_menu.html.slang doesn't exist. (Exception)

  1. place into view == render(partial: "src/views/shared/deep/_menu.html.slang") all ok

Expected behavior: I do not have to specify the full path from project root to subfolder partials

Actual behavior: If my partial view is in a deep subfolder - I have to specify the full path from project root

Reproduces how often: 100%

Versions

Amber CLI (amberframework.org) - v0.6.7

Crystal 0.24.2 [4f9ed8d03] (2018-03-08)

LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu

OS: Ubuntu 17.10 artful

Additional Information

It's just an unusual behavior. It just takes time to figure out how it should work. It's not intuitive. But this is not a critical bug, so just a question, will you do anything about it?

faustinoaq commented 6 years ago

Hi, thank you for reporting this issue

I think we should add src/view as default folder for partial: files as well.

We already use this behavior with non-partial views, although I don't know if crystal macros can allow us to do that using partial:.

elaine-jackson commented 5 years ago

Is this still an issue? I'm looking at render.cr and it looks like templates and partials aren't treated differently in how the file is found. If it's having trouble finding the partial it seems like a bug.

module Amber::Controller::Helpers
  module Render
    LAYOUT = "application.slang"

    macro render(template = nil, layout = true, partial = nil, path = "src/views", folder = __FILE__)
      {% if !(template || partial) %}
        raise "Template or partial required!"
      {% end %}

      {{ filename = template || partial }}

      # Render Template and return content
      {% if filename.id.split("/").size > 1 %}
        %content = render_template("#{{{filename}}}", {{path}})
      {% else %}
        {{ short_path = folder.gsub(/^.+?(?:controllers|views)\//, "") }}
        {% if folder.id.ends_with?(".ecr") %}
          %content = render_template("#{{{short_path.gsub(/\/[^\.\/]+\.ecr/, "")}}}/#{{{filename}}}", {{path}})
        {% else %}
          %content = render_template("#{{{short_path.gsub(/\_controller\.cr|\.cr/, "")}}}/#{{{filename}}}", {{path}})
        {% end %}
      {% end %}

      # Render Layout
      {% if layout && !partial %}
        content = %content
        render_template("layouts/#{{{layout.class_name == "StringLiteral" ? layout : LAYOUT}}}", {{path}})
      {% else %}
        %content
      {% end %}
    end

    private macro render_template(filename, path = "src/views")
      Kilt.render("#{{{path}}}/{{filename.id}}")
    end
  end
end
eliasjpr commented 3 years ago

In regards to this issue I recommend to look into this template engine https://github.com/straight-shoota/crinja