Define a parent template and extend it in ruby on rails 4 like it is done in twig with "extends" - ruby-on-rails

In twig i can have a parent layout which defines some standard
<!DOCTYPE html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2011 by you.
{% endblock %}
</div>
</body>
</html>
and then have a child layout which override some or all the blocks
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ parent() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
</p>
{% endblock %}
how can i do something similar in Rails 4?I looked around a bit but didn't find it.

You can create a layout for each controller. news.html.erb for NewsController etc.
You can then use content_for?, yield and render to nest the controller specific layouts inside application.erb.html
Here's an example from official rails guides.
In app/views/layouts/application.html.erb:
<html>
<head>
<title><%= #page_title or "Page Title" %></title>
<%= stylesheet_link_tag "layout" %>
<style><%= yield :stylesheets %></style>
</head>
<body>
<div id="top_menu">Top menu items here</div>
<div id="menu">Menu items here</div>
<div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
</body>
</html>
In app/views/layouts/news.html.erb:
<% content_for :stylesheets do %>
#top_menu {display: none}
#right_menu {float: right; background-color: yellow; color: black}
<% end %>
<% content_for :content do %>
<div id="right_menu">Right menu items here</div>
<%= content_for?(:news_content) ? yield(:news_content) : yield %>
<% end %>
<%= render template: "layouts/application" %>
Source: http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts

Related

Coverting jade to handlebars

I am trying to convert the layout.jade to handlebars. What are the equivalents of block content and block sidebar, please?
doctype html
html(lang='en')
head
title= title
meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1')
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css')
script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js')
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js')
link(rel='stylesheet', href='/stylesheets/style.css')
body
div(class='container-fluid')
div(class='row')
div(class='col-sm-2')
block sidebar
ul(class='sidebar-nav')
li
a(href='/catalog') Home
li
a(href='/catalog/books') All books
li
a(href='/catalog/authors') All authors
li
a(href='/catalog/genres') All genres
li
a(href='/catalog/bookinstances') All book-instances
li
hr
li
a(href='/catalog/author/create') Create new author
li
a(href='/catalog/genre/create') Create new genre
li
a(href='/catalog/book/create') Create new book
li
a(href='/catalog/bookinstance/create') Create new book instance (copy)
div(class='col-sm-10')
block content
Converted to the following. I have covered the "block content" and "block sidebar" to {{{content}}} and {{{sidebar}}} respectively.
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-2">
{{{sidebar}}}
<ul class="sidebar-nav">
<li> Home</li>
<li> All books</li>
<li> All authors</li>
<li> All genres</li>
<li> All book-instances</li>
<li>
<hr>
</li>
<li> Create new author</li>
<li> Create new genre</li>
<li> Create new book</li>
<li> Create new book instance (copy)</li>
</ul>
</div>
<div class="col-sm-10"> {{{content}}}
</div>
</div>
</div>
</body>
</html>
I have tried jade-to-handlebars and pug-to-handlebars but none of them utilities work!
Thank you very much in advance.

Creating another layout template for a Site made with Ruby on Rails

I'm trying to create two separate layout templates in ruby because everything is defaulting to the application.html.er layout, but I can't seem to get it right. Ive tried about 5 solutions on here and none of them seem to work for my code. Please someone help?
app/controllers/pages_controller.rb :
`
class PagesController < ApplicationController
def home
layout :homeLayout_layout
end
end
`
views/layouts/homeLayout.html.erb:
`
<!DOCTYPE html>
<html>
<head>
<title>Checklance</title>
<%= stylesheet_link_tag "//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css", "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js", "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
<link href='http://fonts.googleapis.com/css?family=Poiret+One' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Changa+One' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
padding-top: 50px;
}
</style>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" id="navbar">
<div class="container" id="body">
<a id="nav" class="navbar-brand" href="/projects">
<img src="http://i1051.photobucket.com/albums/s423/Kira-Banks/check-2.png" id="logo">
Checklance
</a>
</div>
</div>
<div class="container" id="homeContainer">
<%= yield %>
</div>
<footer id="footer">Copyright 2014 Kira Banks</footer>
</body>
</html>
`
views/pages/home.html.erb :
`
<h1 id="homeTitle">Welcome!</h1>
`
Thanks in advance!
Your file names should all be snake_case in Rails. Change views/layouts/homeLayout.html.erb to views/layouts/home_layout.html.erb and your controller should look like:
class PagesController < ApplicationController
def home
render layout: "home_layout"
end
end
Also you can mention the newly created layout top of the controller. So, that will be effective in all action's of the respective controller and your controller should look like:
class PagesController < ApplicationController
layout: "home_layout"
def home
end
end

Template Partial/Snippet only Renders Plain Text

How do I get blocks inside a Liquid template snippet to render inside Rails? Currently, I am able to render plain text snippets, for example a layout might be:
<!DOCTYPE html>
<html>
<head>
{% include 'stylesheets' %}
</head>
<body>
</body>
</html>
If _stylesheets.liquid is plain text, this works fine. However, if I do something slightly more complicated, such as:
<!-- _stylesheets.liquid -->
{% for stylesheet in stylesheets %}
{{ stylesheet.file_url | stylesheet_tag }}
{% endfor %}
This will render nothing. When placing the exact code in the layout, it renders the expected results:
<!-- This Works -->
<!DOCTYPE html>
<html>
<head>
{% for stylesheet in stylesheets %}
{{ stylesheet.file_url | stylesheet_tag }}
{% endfor %}
</head>
<body>
</body>
</html>
Here is how I am rendering the liquid, in my rails view:
<%= Liquid::Template.parse(#theme.layout)
.render('stylesheets' => #theme.stylesheets)
.html_safe
%>
I was able to get the snippet partial working by changing the code to the following:
<!-- Layout -->
<head>
{% include 'stylesheets' %}
</head>
<!-- Partial: _stylesheets.liquid -->
{{ stylesheets.file_url | stylesheet_tag }}
This iterates through each stylesheet, but I cannot for the life of me find out why it does so without a liquid for loop.
Any ideas why this works?

Why is Flask-WTF Form presenting 404 error with POST requests and not GET

I have been looking at this for a while, trying to get this form to recognize the POST, and instead it generates a 404 error.
Views
from flask import *
from dockteck.models import EmailForm
from dockteck import app
# Page Routing
#app.route('/')
def main():
return render_template('index.html')
#app.route('/contact', methods=['GET', 'POST'])
def contact():
form = EmailForm()
if request.method == 'POST':
return "Message Sent"
elif request.method == 'GET':
return render_template('contact.html', form=form)
#app.route('/portfolio')
def portfolio():
return render_template('portfolio.html')
I have a simple contact function, that is working fine when a page GET is requested. The following contact page loads for a page GET:
{% extends "template.html" %}
{% block content %}
<h1>Contact Me</h1>
<form action="{{ url_for('contact') }}" method=post>
<div class="row">
<div class="large-4 columns">
{{ form.name.label }}
{{ form.name }}
</div>
<div class="large-4 columns">
{{ form.email.label }}
{{ form.email }}
</div>
<div class="large-4 columns">
<div class="row collapse">
{{ form.subject.label }}
{{ form.subject }}
</div>
</div>
</div>
<div class="row">
<div class="large-12 columns">
{{ form.comment.label }}
{{ form.comment }}
</div>
</div>
<div class="row">
<div class="large-6 columns">
{{ form.submit }}
</div>
</div>
</form>
{% endblock %}
Upon submit of this form, it returns a 404 error page, as it requests contact via POST. Additionally, with firefox dev tool inspection, it shows that the page is posting the correct page /contact, but times out with a 404 error, and gives this additional message:
The character encoding of the HTML document was not declared. The
document will render with garbled text in some browser configurations
if the document contains characters from outside the US-ASCII range.
The character encoding of the page must be declared in the document or
in the transfer protocol.
In the template file, I have tried a few varying declarations, but it doesn't seem to make a difference:
<!DOCTYPE html>
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />
Let me know if I'm missing anything that would be helpful to solve this problem.
Edit: Here is EmailForm
from wtforms import Form, TextField, TextAreaField, validators, SubmitField
class EmailForm(Form):
name = TextField('Full Name')
email = TextField('Email Address')
subject = TextField('Subject')
comment = TextAreaField('Comments')
submit = SubmitField('Send message')
try to change these things :
from method=post to method="POST"
from form = EmailForm() to form = EmailForm(request.form)
and tell me if you still have any error

Master/application layouts with Erlydtl

What's a nice way to do master/application layouts with Erlydtl? With master/application layout I mean separating the main page layout template from template with the pagecontent, but rendering them as one. Think Ruby on Rails application layouts or ASP.NET Master Pages.
Are you trying to achieve something like:
main.dtl
<html>
<head></head>
<body>
<div id="menu">Menu</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
page.dtl
{% extends "main.dtl" %}
{% block content %}
Here's my content
{% endblock %}

Resources