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

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

Related

How do you pass local variables to views in Kemal?

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>

Custom JSON renderer in AEM/Sling

I've been playing around with this for a while now, and I think, I've - almost - cracked it, but I am still not fully satisfied with my solution.
So, what I want to do, is having a piece of content, a list of items, which would have two views: The standard HTML one, so people can view and edit it; and then a JSON endpoint for other services to consume.
First I thought it's a simple matter of creating two JSP scripts to render the content:
/apps/my-stuff/components/list-page/html.jsp
/apps/my-stuff/components/list-page/json.jsp
However the Apache Sling DefaultServlet seems to be rather ignorant of the json.jsp script.
As a second attempt, I created another script, in /apps/foundation/components/primary/cq/Page/json.jsp which will be actually called, and renders the page, as I expected. However there are a couple of worries/questions regarding this:
First of all, why is this being honoured by the system, and not the one in the more specific place?
The documentation states, that to find the appropriate renderer, first sling:resourceType will be inspected, then sling:resourceSuperType and then, only as a fallback will jcr:PrimaryType checked. However I think this is rather: jcr:PrimaryType, then the DefaultServlet, and then all the other things.
Most worryingly however, I have to admit, this is rather generic, so it'll break all the contnet with jcr:PrmaryType = Page, so that could have some side-effects.
A solution could be creating a new type: ListPage extends Page; and then create a renderer for that in /apps/foundation.... However I have this bad feeling, that might introduce other problems.
So my question is two fold: What is the proper way of doing this, and/or what am I missing from the way the URL -> script resolution is working in AEM/Sling. (Because it seems to be slightly different that described here and here.)
(Obviously I am trying to keep the default JSON renderer for other pages, as that might be needed for other things in the page. I am not even sure, changing this one page won't break the UI for this particular page...)
However the Apache Sling DefaultServlet seems to be rather ignorant of the json.jsp script.
Have you tried renaming your JSP like so: "list-page.json.jsp"?
If you're using AEM 6.3, you should look at Sling model Exporters. They allow you to automatically register a servlet against your Sling Model (that you can create to model your list content). That servlet can generate a JSON representation of the model for you using Jackson.
If you're not using AEM 6.3, I would suggest you create a servlet registered against your resource type and use an additional selector.
#SlingServlet(
selectors = "json",
resourceType = "my-stuff/components/list-page",
methods = "GET")
More information on Sling Servlets can be found here.

Yii2 best practices translating dynamic content

Can anyone share own experience and best practices implementing multilingual sites with Yii2? I want translate user input that is stored in database. For example article, that may have its name in three different languages, body and some translatable attributes as well.
Does Yii2 have built in features to translate the dynamic content? Or should I use third party extensions like these ones below:
https://github.com/creocoder/yii2-translateable
https://github.com/LAV45/yii2-translated-behavior
https://github.com/lajax/yii2-translate-manager
Your help would be appreciated.
Well, I can give you my point of view only based on what I have done.
There are to places to work translation
The non dynamic strings managed with i18n and messages system from
yii, that will help you with static content.
Working the translated routes dynamically with a bootstrapped class, that allows you to build this routs when the app is built.
And working with tables that have columns that support the translation like 'title_en, title_es', and as many as you need to translate. Actually in your admin interface you may want to use something like yandex to help you translating the content to this fields.
Now I will explain:
The i18n Message Translation is based on translating strings in your views, models, and in some cases like on the bootstrapped class.
You will en using Yii::t('app/main', 'Your name is {0}' as an example to translate strings that are stored on message php files.
Now if you translate stings you will want to translate the routes so you will en with routes like /articles and /articulos when you change the language.
for this purpose you will like to build a class that implements BootstrapInterface and that will be called from the process of bootstrapping your app.
So this is an example of my settings.php that I use for this
namespace app\base;
use Yii;
use yii\base\BootstrapInterface;
class settings implements BootstrapInterface {
public function __construct() { }
public function bootstrap($app) {
/// Dynamic translated routes
$t_articles = Yii::t('app/route', 'articles');
$app->getUrlManager()->addRules([
'/'.$t_articles => '/articles',
], false);
}
}
And remember to bootstrap the class in your config file «i.e. web.php»
'bootstrap' => [
'log',
'app\base\settings',
],
And finally to translate text from the database you may want to make a table that supports the translated text like:
CREATE TABLE articles (
id INT,
title_en VARCHAR(20),
title_es VARCHAR(20)
);
So when you call your app you can pull your data using something like the following on the action (only a simple example):
$articles = ArticlesA::find()->where(['id' => 1])->one();
$lang = $this->module->language;
return $thi
s->render('index',['articles'=>$articles, 'lang'=>$lang]);
or in the view as:
<p class="lead"><?=$articles['title_'.$lang]?></p>
I hope this explains the way I have been translating my apps.
Use a Google translator API or Yandex API to for smooth translations for multiple languages.
Few links that i have found on git
https://github.com/borodulin/yii2-i18n-google
Tutorial
RichWeber/yii2-google-translate-api
Google Api is a paid service however you can get free credit for 12 months if your a first time user

How can I use xxx.scala.html in Play2.0 framework Controller

I am a fresh man, using play2.0 framework. Now I have a trouble to use xxx.scala.html. In Eclipse I added a xxx.scala.html, but I cannot use "xxx.render()" function to render my html.
Now I create a form1.scala.html in view package. I want to render this html in controller like this "return ok(form1.render());". But it cannot. Why I cannot?
I have checked Play-Sample(example: 'form' application). In this application controller class, he used form1.scala.html, form2.scala.html, summary.scala.html and so on defend by himself.It's Ok. But I cannot use like this.
views is a regular Scala/Java package, but when the template compiler runs it adds a 'html' package under that which it places the compiled templates in. So the source app/views/myTemplate.scala.html results in the function views.html.myTemplate
The view templates are functions themselves, not classes or objects, the filename becomes the function name, there is no render() method.
So if you have the file app/views/myTemplate.scala.html you will be able to use it like this:
Ok(views.html.myTemplate())
or
import views.html.myTemplate
Ok(mytemplate())

Grails with JAX-RS vs UrlMappings for RESTful Services

I started out looking at the JAX-RS plugin for grails and thought that was the way to go mainly because it was based on JSR-311 and I figure following standards is usually the smart thing to do. However, using Grail's UrlMappings it seems I basically achieve the same thing. I figure I'm missing something, however, we aren't doing anything overly complex. We basically just need to expose CRUD via an API. Example of doing the same thing with both versions:
JAX-RS:
#PUT
#Consumes(['application/json'])
#Produces(['application/json'])
Response putUser(User user) {
user.save(flush:true)
ok user
}
Grails:
def update = {
def user = new User(params['user'])
user.save(flush:true)
render user as JSON
}
Obviously, this is an overly-simplified example and like I said, maybe I'm missing something important. Also, the nice thing about the Grails built in mechanism is I can utilize Content Negotiation along with it.
Anyone have any opinions on this?
I had to make the same decision, and I found it just easier to use URL Mappings because the API was not that complex and there were a limited number of API calls that needed to supported.
If came down to what would be easier to maintain based on the LOE and the resources able to support the implementation.
The jax-rs plugin is very useful if you are creating web services straight to your domain models. It gives you a "generate-resource" command that automatically creates CRUD apis for your model.
grails generate-resource mydomain.Model
This part seems to work fine, however, I encountered quite a few bugs/problems with the plugin that I finally had to implement the REST services using URL-mappings.
Although the URL-mapping method seems to be more coding, it works perfectly.
import grails.converters.JSON
class ModelServiceController {
def id = params.id
def myModel = MyModel.findById(id)
render myModel as JSON
}
Here's the link for grails REST
http://grails.org/doc/1.0.x/guide/13.%20Web%20Services.html