Skip to main content

kemal-view

Rendering ECR templates and layouts with Kemal.

소스 정보

저장소
kemalcr/kemal
최근 소스 활동
2026년 8월 21일 14:44
감지된 SKILL.md 언어
영어
스타
3,924
포크
206

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
kemal-view
description
Rendering ECR templates and layouts with Kemal.
license
MIT
# Kemal View Rendering This skill provides expert guidance on rendering HTML templates using ECR (Embedded Crystal) in Kemal, strictly following patterns from [`kemal-by-example`](https://github.com/sdogruyol/kemal-by-example). ## Core Mandates - **Rendering:** Use `render "path/to/view.ecr"` for simple rendering. - **Layouts:** Use `render "path/to/view.ecr", "path/to/layout.ecr"` for layout support. - **Paths:** Always use relative paths from the project root (e.g., `src/views/index.ecr`). - **Data Passing:** Local variables in the route block are directly accessible within ECR templates. - **Escaping:** ECR does not auto-escape. Wrap user-provided values in `HTML.escape(...)` (`require "html"`) when outputting with `<%= ... %>`. ## Patterns from Source Code ### Basic Route with View Rendering ```crystal # blog/src/routes/posts.cr get "/posts" do posts = Post.all render "src/views/posts/index.ecr", "src/views/layouts/application.ecr" end ``` ### Route with Local Variables for Views ```crystal # ecommerce/src/routes/auth.cr get "/signup" do |env| current_user = Ecommerce::Auth.current_user(env) cart_count = if (user = current_user) && (uid = user.id) CartItem.total_quantity_for_user(uid) else 0_i64 end error_message = nil render "src/views/auth/signup.ecr", "src/views/layouts/application.ecr" end ``` ### Edit Route with Conditional Rendering ```crystal # blog/src/routes/posts.cr get "/posts/:id/edit" do |env| id = env.params.url["id"]?.try(&.to_i64?) post = id ? Post.find(id) : nil if post render "src/views/posts/edit.ecr", "src/views/layouts/application.ecr" else env.response.status = :not_found "Post not found" end end ``` ### Layout Template Structure Typical layout file at `src/views/layouts/application.ecr`: ```html <!DOCTYPE html> <html> <head> <title>My App</title> </head> <body> <nav> <!-- Navigation content --> </nav> <main> <%= content %> </main> <footer> <!-- Footer content --> </footer> </body> </html> ``` ### View Template Example Typical view file at `src/views/posts/index.ecr`. ECR does **not** auto-escape output, so any user-provided value rendered with `<%= ... %>` must go through `HTML.escape` (stdlib, `require "html"`) to prevent XSS: ```html <h1>Posts</h1> <% posts.each do |post| %> <article> <h2><%= HTML.escape(post.title) %></h2> <p><%= HTML.escape(post.body) %></p> <a href="/posts/<%= post.id %>/edit">Edit</a> </article> <% end %> <a href="/posts/new">New Post</a> ``` ### Error Rendering with Local Variables ```crystal # ecommerce/src/routes/auth.cr post "/login" do |env| email = env.params.body["email"]?.try(&.strip) || "" password = env.params.body["password"]?.try(&.strip) || "" user = User.authenticate(email, password) if user Ecommerce::Auth.sign_in(env, user) env.redirect "/products" else current_user = nil cart_count = 0_i64 error_message = "Invalid email or password." env.response.status = :unprocessable_entity render "src/views/auth/login.ecr", "src/views/layouts/application.ecr" end end ``` ## Best Practices - **Layout Structure:** Use `<%= content %>` in layout files to render the view content. - **Partials:** Use `render "path/to/_partial.ecr"` for reusable UI components (not shown in examples but standard practice). - **ECR Directives:** Prefer `<%= ... %>` for output and `<% ... %>` for logic/control flow. - **Escaping (XSS):** ECR performs no automatic HTML escaping. Always wrap user-provided data in `HTML.escape(...)` inside `<%= ... %>`; only render raw HTML you generated yourself (like the layout's `<%= content %>`). - **Local Variables:** Pass data to views by defining local variables in the route block before calling `render`. - **Error Handling:** Handle missing resources (404) by checking models before rendering, or set appropriate status codes. ## When to Use - When creating or modifying HTML views in a Kemal application. - When setting up or changing the main application layout. - When organizing view files and partials.
GitHub에서 보기