phoenix: render template of other folder - templates

I have two template folder in my web/templates folder:
> ls web/templates
personal_info user
What I want is to render some template from user folder in another view of personal_info. so I have a file at path: web/templates/personal_info/index.html.eex, I have following content:
<%= render "user/xyz.html" %>
But I get following error:
[error] #PID<0.821.0> running MyApp.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /
** (exit) an exception was raised:
** (Phoenix.Template.UndefinedError) Could not render "user/xyz.html" for MyApp.PersonalInfoView, please define a matching clause for render/1 or define a template at "web/templates/personal_info". The following templates were compiled:
* index.html
Please tell me how do I render template defined in other folder, I tried few permutations, but none worked.

Phoenix templates are just functions, so when you want to render your UserView's "xyz.html" template from your PersonalInfo's view, you just call the function!
Let's say you are inside the web/templates/personal_info/show.html.eex template. (Phoenix.View.render is already imported for you):
<%= render UserView, "xyz.html", user: user %>
Of if you want to pass along all the template assigns that your PersonalInfo template was provided:
<%= render UserView, "xyz.html", assigns %>
As you found, this works from anywhere, because templates are Just Functions. For example, the same thing would work in iex:
iex> Phoenix.View.render(MyApp.UserView, "xyz.html")
"<h1>User ..."

As of Phoenix 1.5.1
Phoenix matches controllers, views, and templates by names. It can be changed by put_view like:
conn
|> put_view(MyAppWeb.SpecialView)
|> render(:show, message: "Hello")
https://hexdocs.pm/phoenix/Phoenix.Controller.html#render/3-views

For me worked when I specified application name:
web/templates/product_gallery/index.html.eex:
<p>Please, render me!</p>
web/templates/kitchen/index.html.eex:
<%= render APP.ProductGalleryView, "index.html", assigns %>
If I am trying to render without application name I am getting:
undefined function ProductGalleryView.render/2 (module ProductGalleryView is not available)

I'm on Phoenix 1.3.0. Seems like I had to add
alias MyApp.Userview
to web/views/personal_info_view.ex, then
<%= render conn, UserView, "xyz.html" %>
Without the alias above, then you have to
<%= render conn, MyApp.UserView, "xyz.html" %>

Apparently following worked:
<%= Phoenix.View.render(MyApp.UserView, "xyz.html") %>
please let me know, If there are better alternatives.
Source: this.

Related

In Rails, how do I define a "_new_path"?

I’m using Rails 4. How do I define a “_new_path” in my routes.rb file? I’m tryhin got create an admin area where an admin can create objects. So I have this in my config/routes.rb file
get 'admin/index'
get 'admin/list'
get 'admin/add'
get 'admin/approve'
Then in my app/views/admin/_add.html.erb file, I have
<%= form_for #my_object do |f| %>
but when I visit my page, I get the error
undefined method `my_objects_path' for #<#<Class:0x007ffea5de2c80>:0x007ffea5dd9798>
Did you mean? my_objects_new_path
I want the form to submit to the “create” method in my controller. How do I set this up?
try this commande rake routes to show yours paths rake routes
admin_index GET /admin/index(.:format) admin#index
admin_list GET /admin/list(.:format) admin#list
admin_add GET /admin/add(.:format) admin#add
admin_approve GET /admin/approve(.:format) admin#approve
after in app/views/admin/_add.html.erb file
<%= form_for admin_add_path do |f| %>

How to set name of class in .yml in Rails

I have an_errors.html.erb that takes an object and has
<%= object.class.name %>.
It is called by this in a _form.html.erb:
<%= render 'shared/errors', object: #product %>
What should I write in my xx.yml file to find the translation?
I have
models:
product: Produkt
which doesn't do the job.
Any clues?
Cheers Carl
I'm not quite clear on what you are going after, however, the following might work.
In your YAML file:
models:
product: 'Product'
In your ERB view:
# The following assumes "object" in your original post relates to the string (Product) in the YAML file
<%= object.constantize %> # this outputs the details of your class
<%= object.constantize.to_s %> # would be a string representation of your class (i.e., 'Product')
API docs for Constantize
Again, was not 100% sure what you were looking to accomplish but wanted to offer the suggestion in the event it helps!

Simple-navigation: undefined local variable or method `root'

I installed and configured simple-navigation as decribed here (simple-navigation configuration).
I modified config/navigation.rb (contains only one menu item):
primary.item :key_1, 'Home', root
My config/routes.rb contains:
root 'static_pages#home'
rake routes contains string:
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
app/views/layouts/application.html.erb contains:
<%= render "layouts/header" %>
app/views/layouts/_header.html.erb contains:
<%= render "layouts/main_nav" %>
and app/views/layouts/_main_nav.html.erb contains one string:
<%= render_navigation %>
After that I got an error:
Showing <...>_main_nav.html.erb where line #1 raised:
undefined local variable or method `root'
Why restful route helpers and named route helpers are "invisible" in this case? I tried all of the prefixes from the routes table.
The 3rd argument should be an URL or path, so change root to root_path in config/navigation.rb. Your menu item should look like:
primary.item :key_1, 'Home', root_path

Rails 4 using partials in a mailer view

I have here a problem with partials in a view of an ActionMailer. They just do not work - and I do not know, if I do something wrong, this is a bug or this is not supported at all.
This should be working as this would be needed to have also DRY code in the mailer views (. From my testings, I see, that helpers are working (after including them into the ActionMailer class)
I am using: Rails 4.0.0 on Ruby 2.0.0-p247
Error Message:
ActionView::MissingTemplate at /events/81/user_invitations
==========================================================
> Missing partial user_invitation_mailer/test_partial with {:locale=>[:en], :formats=>[:text], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}. Searched in:
* "/Users/user/Sites/participate/app/views"
* "/Users/user/.rvm/gems/ruby-2.0.0-p247/gems/devise-3.4.0/app/views"
But this partial is there! - I am not allowed to upload pictures... structure is:
- views
-- user_invitation_mailer
--- _test_partial.html.erb
--- user_invitation.text.erb
Details:
call in the Controller:
UserInvitationMailer.user_invitation(#invitation).deliver
UserInvitationMailer:
class UserInvitationMailer < ActionMailer::Base
add_template_helper(MailerHelper) # for testing including helpers.
def user_invitation(invitation)
#invitation = invitation
mail(to: #invitation.email, subject: 'Invitation')
end
end
user_invitation.text.erb:
Hi <%= #invitation.email %>,
This is a test email see:
<%# test_helper %>
<%= render partial: 'test_partial' %>
Thanks
_test_partial.html.erb:
"Test the partial."
(adding:)
Not working:
<%= render partial: 'test_partial' %>
<%= render partial: './test_partial' %>
<%= render partial: '../test_partial' %>
<%= render partial: 'user_invitation_mailer/test_partial' %>
The rails console give you nice explanation where it is looking for partials:
Missing partial user_invitation_mailer/test_partial with {:locale=>[:en], :formats=>[:text], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}.
Searched in:
"/Users/user/Sites/participate/app/views"
So the root folder for partials is your views folder.
You can create new folder:
/views/partials/_some_partial.html.erb
and in your template:
render "partials/some_partials", local_variables: #model.some_variables
or just render full path partial:
render "/user_invitation_mailer/test_partial"
UPD
For complete answer please see comments below
in rails 4 you can try with <%= render 'test_partial' %> it will work.
Were you able to find a solution? I am having the same issue. But able to render a partial if defined some shared folder.
Edit - Found the issue. I was not properly closing the call.

How to render a view inside of another view (rails 4)

Hi I want to preface this by saying that I am new to coding.
I have an issue that I believe can be solved in two ways
A. by rendering a partial
B. by updating the controller
( I can totally be wrong but these are what I suspect lol)
I have two controllers/views "reviews" and "logs". and I want them to both appear on the same page.
How can I do this?
I tried rendering a partial but I alway get an error.
and I tried the piece of code below:
which made my reviews show up on the page, but when I add
#log = #user.logs.all
to it, it doesn't pull all the logs to the page like it does for the reviews.
def show
#user = User.find_by_name(params[:id])
if #user
#reviews = #user.reviews.all
render action: :show
else
render file: 'public/404', status: 404, formats: [html]
end
end
First things first. Views refer to actions in controllers. So there can be several views for each controller or even none.
So, if you want to render #reviews and #logs on the same page you should first instantiate both instance variables in the same action and then render both partials in the same action.
How do you do that? Easy.
First you got to the controller you just showed and edit that show action.
def show
# You can set the variable in the if-clause
# And you also need to use static finders with a hash as an argument in Rails4
if (#user = User.find_by(name: params[:id]))
#reviews = #user.reviews.all
#logs = #user.logs.all
# You don't need to call render explicitly
# if you render the view with the same name as the action
else
render file: 'public/404', status: 404, formats: [html]
end
end
Second: you go to your /app/views/reviews/show.html.erb template and put both partials there like this (this is just an example, adjust your markup to fit your needs).
<h1> Reviews and Logs</h1>
<div id="reviews_part">
<%= render #reviews %>
</div>
<div id="logs_part">
<%= render #logs %>
</div>
Now create 2 new partials /app/views/reviews/_review.html.erb and /app/views/logs/_log.html.erb and put all the needed markup there (use regular variables review and log to adress the repeating objects). Rails will automaticaly repeat those partials as many times as needed.
Or you can explicitely call the partial render
<div id="reviews_part">
<% #reviews.each do |review| %>
<%= render review %>
which is the same as
<%= render partial:"reviews/review", locals:{review:review} %>
<% end %>
</div>
Here is the way of rendering partials into views in HAML:
=render :partial => "header"
%h2 Hello World
=render :partial => "footer"
Every partial you render this way, has to be created within the same folder.
Each partial's name has to begin with an underscore (_). This should be the view's directory:
- home
- index.html.haml
- _header.html.haml
- _footer.html.haml