How do you pass local variables to views in Kemal? - html

Edit: Link for documentation
I'm new to Crystal and I'm trying to build a small web-app with Kemal framework.
I have some experience working with Ruby and it's frameworks (Rails and Sinatra).
In Rails/Sinatra you can pass local variables to views that you are about to render. Something like this:
render(:some_view, locals: { foo: :bar })
Variable foo with value bar will become available in view.
So I thought that the same goes here, but I can't find anything like that in Kemal guide or their GitHub page nor in their Cookbook pages.
What am I missing here?
Maybe there is some other completely different way of doing this in Kemal that I'm not aware of?

Define variable in the controller
get "/" do
name = "Sergey"
render "src/views/main.ecr"
end
Use it in the view
<body>
My name is <%= name %>
</body>

Related

Switch between 2 or more templates with an action in controllers?

I have a default Phoenix application. This app will have a page_controller
which will load an index.html.eex file.
The app will know to use the view to access templates/page/index.html.eex.
Now say you have created another html page which is identical to index.html.eex in every way except it is in French.
As we do not want to create a whole new Phoenix application which will have all the same code, with the exception being the French translation of the current page/index.html.eex, is there a way to tell
the view or the controller which file needs to be loaded.
Is there a plug which can be placed in the router to alter where render will look for it's templates?
First of all I would suggest you to use Gettext to use labels for French pages.
For example you can all French templates keep in the very same folders (to don't change logic for view), but to name them with suffix eg. "index_fr.html.eex" etc. and then you can write quite simple helper (not necessarily a plug) that will add to all of your templates this suffix.
Still, I would recommend you using Gettext - template's source code is only in place and almost all of the logic Gettext handles for you.
I suggest you pick the #patnowak's answer. Use Gettext, that's the tool made for translation and is powerful enough.
If you still want to do it, remember render/3 in controller calls render/2 functions defined in views, if defined. If not, it runs default rendering function and looks for the template. Read docs for more information.
So for example, this is the controller:
def index(conn, params) do
# defined assigns as you wish
render(conn, "index.html", assigns)
end
Now, define this in the view:
def render("index.html, assigns) do
case assigns[:lang] do
"fr" -> render("index_fr.html", assigns)
_others -> render("index_en.html", assigns)
end
end
You may also write a plug to automatically put :lang into assigns:
def lang_plug(conn, opts) do
conn
|> fetch_query_params()
|> (fn cn -> assign(cn, :lang, cn.query_params[:lang] || "en").()
end
Look Plug.Conn to see docs of fetch_query_params/1 and assign/3, and also other functions to fetch language from other places like headers or body.
You get the idea. In the plug, fill assigns with :lang, fetch them inside your defined render function and act appropriately.
Still, Don't do this. Using Gettext is the proper way.

How to render HTML using a Ruby on Rails 5 API Application

We're using Ruby on Rails 5.0.0.1 in API-Mode. What Middleware and Configurations do I need to add, in order to being able to render html instead of json in an controller.
Edit:
Thank you all for your answers.
Want I wanted is to render normal erb/haml views. not html in json like 'kartik upadhyay' mentioned. Since the Application is primary an JSON API we didn't want the full blown default Rails Installation, which mean our Application Controller extends from ActionController::API.
My Plan was to make a PdfRendering Controller which includes all Modules needed for ActionView to work. What I rather did was reading the asset pipeline (because we wanted to use sass) and inherit the application controller from ActionController::Base. as other rails apps would do.
It's not the nicest solution since you're including the whole ActionController::Base and all of it's Feature that you may not be using. But it's still slimmer that a full Blown Rails installation (especially the middleware aka. sessions etc.)
include ActionView::Layouts
include ActionController::Rendering
Add these to your controller
You can use render to string method of rails for rendering your html as string inside json, put this inside your controller:
render json: { data: render_to_string('html_file_name') }
this will render html as response like:
{"data": "<html>\n<h3>hello</h3>\n</html>"}
you can render erb/haml/slim etc. files like the following:
format.html { render :file_name }
You can simply use this gem RABL.
https://github.com/nesquena/rabl

Call a controller inside a template and another controller in Fatfree framework

i'd like to know if i can call a controller action inside a template, and inside another controller in fatFree framework (F3).
I'm not sure if i understand you corrently, but calling a Class method in Template would go like this:
{{ MyConroller->doSomething() }}
Of cause you could call one controller within another too... just use raw php
$obj = new MyController();
$obj->foo();
or use the F3 call method $f3->call('MyController->doSomething');
Also check out the new API docs.
http://fatfreeframework.com/base#call
It's still under construction, but hopefully you'll find more information about this or any other framework part very soon.
Many MVC purists would balk at the idea of a View (template) calling methods on the Controller. They would say that the controller needs to provide the data that the view needs, or at least give it the Model, so that it can retrieve data from there.
Furthermore, the View probably shouldn't be doing anything (or asking another component to do anything), other than generating the display. But can query the Model for data. But maybe by doSomething() you do mean getSomeData().
While I'm not an MVC purist I do agree with the idea of keeping logic and functionality out of the view if at all possible.

Ruby on Rails: Adding a second custom view to a controller (Rails 3)

Rails 3:
I'm pretty new to rails and so far it's all gone really well but I'm having a little trouble understanding all of this routing stuff.
I'm now trying to add a second view to my controller but I don't want to use any of the show, edit, index, etc. actions.
I want to a custom name for the view and a custom action in the controller. Could someone please explain to me how to do this.
And also I would really like to know how to link to it from another view using the "link_to" method.
Any help is greatly appreciated!
I often use rest and for creating custom actions and views I just use routes
resources :news , :only => [:index] do
collection do
get :events
get :hot
get :last
end
member do
get :vote
end
end
so I created 3 actions for collection of resource and 1 for resource
you can run rake routes from console and see list of routes, there are predefined helpers for every route with postfix _path. example from documentation
new_geocoder_path returns /geocoder/new
edit_geocoder_path returns /geocoder/edit
geocoder_path returns /geocoder

How to include my own Ruby (on rails) functions inside an HTML page

I'm creating a web-app.
While it works great, writing whole pieces of code inside "<% %>" tags in ruby on rails is pretty ugly.
I tried to define a function in my controller.rb and then call it from the html page.
This does not work, as it does not recognize the function.
I'd appreciate any help here. Did I put my function in the correct place? Do I need to load using "require"?
For example:
controller file:
class WelcomeController < ApplicationController
def index
end
def myfunc(x)
puts x
end
end
HTML file (index.html):
<h1>Welcome</h1>
<p>
<%= myfunc(5) %>
</p>
What you are referring to is called a helper in Rails. There are two ways that you could implement this.
Option number one is to place the method you want to access inside a helper module. The most common one is ApplicationHelper which you can find in RAILS_ROOT/app/helpers/application_helper.rb. If you place the method in there it will be accessible from the views.
Another way if you still want/need to have the method in the controller, then you can use the helper_method function like this:
def WelcomeController < ApplicationController
helper_method :my_func
private
def my_func(x)
puts x
end
end
The usage of private is not needed, but only good practice so that the method cannot be accidentally used as a Controller action or something.
Ruby on rails has a Model-View-Controller architecture - in those architectures you can't access the controller from the view.
You could set a variable with the output from your function, and access that variable from your view