Rails take base64 - ruby-on-rails

In rails i need to take a base64 string, and use it to generate a picture in rails. Now i'm having trouble, because i need to interact with AJAX calls (im strictly working on the server side, another guy is doing that client work) to send pictures. So far i've been taking requests in my application by having data transferred through the url (in the AJAX requests) but now im not sure if it's possible to transfer such a huge string through the url. How could i take in the data (like how could he pass it to me) to generate a picture.
Note: i've been using paperclip for my application so far, but now uploading through the form is not an option, it needs to be in an AJAX call where data is passed in a single call.

You're right, most browsers limit the length of a URL. The limit on IE8/9 is 2083 characters. Even if your particular browser has a higher limit, many servers limit the URL length as well (apache's default limit is right around 8k). It would be best to submit the image as a POST request with the data in the POST body.
I would use jQuery to POST JSON data to the server. In the controller, if this is set up correctly, you won't have to do a thing to parse the JSON. ActiveSupport will recognize the content type and parse it out into the params hash automatically.
Actually posting the data will depend on which javascript library you're using. Here's an example in jQuery, which you'd probably want to wire up to the onclick event of a submit button. This assumes you have a named route called process_image. This code would go in your view.
$.post(<%= process_image_path %>, { b64_img: "your_base64_image_data" });
In your controller, you can access the posted data with params[:b64_img]. If you want to return something from the controller back to the client, you can do this in the controller:
render :json => #model_object
And change the jquery call to look like this so you can do something with the return value:
$.post(<%= process_image_path %>, { b64_img: "your_base64_image_data" },
function(data) {
// do something with the data returned by the controller
});
Hope this helps. You can read more about the jQuery post call I used here: http://api.jquery.com/jQuery.post/
Dan

Related

Kirby CMS: how to return Blocks as HTML?

I'm playing with Kirby CMS and using it as a headless CMS. I'm using Blocks field to handle rich content.
In the API, this field is returned as an array of objects:
[
{
"content": {
"level": "h2",
"text": "test"
},
"id": "02d4a71b-cd02-4382-a78c-84ff1e68324b",
"isHidden": false,
"type": "heading"
}
]
Which is great, I think. But in my case, it's annoying, as I should do all the rendering by myself.
Is there a way, or an option, to tell Kirby to render this field as HTML content?
I know there is a $blocks->toHtml() method, but I'm using a standalone React frontend, so I can't use this in my JSX.
You don't have to use the Kirby API directly in order to get content from your Kirby site. Kirby has a few different ways to respond to an ajax request - and that response can be in any format, such as JSON, an HTML snippet, or anything else. Here are a couple of the most often-used ways to achieve what you want.
CUSTOM ROUTE
You could define a custom route, which is like a 'custom api point', that your React interface could send requests to, and which would respond with the block list as an HTML snippet, as required. You could set your route at a URL like:
https://example.com/block-api
In your route, you could then use the toHTML() method, or a snippet(), or any other method, to convert the blocks into HTML that you can then send back as a string in your response.
In your route definition, you could also use a pattern that would allow you to (optionally) request a single block by ID. Your custom route URL for that would look something like this - where the last segment is the block ID:
https://example.com/blocks-api/02d4a71b-cd02-4382-a78c-84ff1e68324b
CUSTOM CONTENT REPRESENTATION
When you try to reach a page in your Kirby site via its normal URL, Kirby will put the page's content into your page's template, and return it as an HTML document. That is the 'default' behaviour. You can, however, override that.
You can define a custom content representation for your page, which tells Kirby that you want to receive the content of your page in a 'different format' - such as JSON, XML, or anything you wish. That 'different format' can even be just an HTML snippet. All you need to do is define a new template for it.
In your case, you could create a content representation that tells Kirby to return a fully-formatted HTML snippet of your blocks only - by creating a template called something like "mypage.blocks.php", with just the HTML for the blocks in it. So, if to access the page normally we'd go to URL...:
https://example.com/mypage
...to get your 'blocks' custom content representation for that page, you'd now go to:
https://example.com/mypage.blocks
Your custom content representation can have its own controller, too. This is useful if you want to get Kirby to send you the HTML code of just one single block, instead of all blocks on the page. You could use a query parameter in your URL to tell the controller which block you want the HTML for. The controller would then check the URL for the query parameter, and if the parameter is there, it returns only the required block. This would enable your React app to get the HTML code for just a single block on the page, by sending a request to an URL like:
https://example.com/mypage.blocks?id=02d4a71b-cd02-4382-a78c-84ff1e68324b

Ruby on rails how to make website that doesn't refresh the page

I'm not even sure how to ask my question.
I know the basics of ruby on rails and I can make a web app. but I now have a project where I want to have a button on a view that sends data to the controller, but I don't want the controller to send me to a different view, instead I want it to send data back to me (maybe in Json format) and populate something in the view with that data retrieved from the database.
Is this possible? If so how would I go about doing it? What tools do I need if this kind of functionality isn't built into rails itself? I don't know anything about it but could ajax help?
Thanks for the guidance!
You have to make it with javascript.
In your case I advise you to use a simple ajax request with jQuery.
http://api.jquery.com/jquery.ajax/
Jquery is a javascript library that allow you to do this.
1) Include jquery in your html:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
2) Make the ajax query:
$.ajax({
url: "/api/your_url",
data: {
test: "parameter send to the rails controller and stored into params"
},
success: function( data ) {
console.log(data);
}
});
What you are referring to is called Ajax. You can use XmlHttpRequest in your client side javascript to send an asynchronous request to the server and register a callback function that will be called on the client when the server responds. In the callback function you can update your webpage with the new information.

Can you piggyback a data response to an Ajax partial rendering

I'm using ajax to update a partial, but i would like to get some data back from the server at the same time.
$('<%=escape_javascript #my_params.to_json%>');
$("#partial").html('<%= escape_javascript(render partial: "view/partial" )%>');
gives me the response with both data and partial rendering in it, but it breaks the Ajax render, so the partial is not rendered.
Using Rails 4, ROR. no errors in the browser or Rails
if i refresh the page i get the result i wanted.
I know this must be easier than i'm making it.
Assuming that you are using js.erb format for rendering ajax page.
Inside the view partial, write the code
run your js code here or assign to global js variable
I'll leave this here for edification, but my friends told me that they would disavow me if i abused a cookie this way. So i switched my implementation, can't afford to lose any friends. They told me to focus on making the turn around time for the ajax call fast. I still needed to know when the object had completed rendering so i simply added a hidden element in the partial and i set its size to zero and wait until the partial rendering changes the height from zero. It was pretty funny to see the interactions with two tabs open to the web page, even though i was planning to use the session ID avoid crosstalk.
Okay, I decided that for my purposes the best way was to put the data in a cookie and just detect when the cookie changed. This allowed me to change the cookie at the end of the send_data command and both get the data for the image position relative to the other image as well as detect when the send_data completed so i could slide the image into place (over the animated wait image).
it looks like this on the server
send_data(image.to_blob { self.format = 'png' },
type: 'image/png',
disposition: 'inline')
cookies[:duck_data] = { :value => $cookie_data.to_json}
and this on the client side
wait_for_paint=->
if $.cookie('duck_data') == 'keep waiting'
setTimeout (->wait_for_paint()), 250
else
my_data= $.parseJSON($.cookie('duck_data'))
do_ajax_response(my_data)

Can I capture a param but avoid showing it in the url?

I would like to capture the id of an element that is clicked on and then pass that id to the controller, all without showing the id in either the link or the url param, and without having to write custom ajax loading. Anything like that available in rails out of the box?
What are you trying to achieve (what's the end goal)? It sounds like you want to communicate between the client and server without using ajax or encoding params in the user's url.
The usual ways of doing that, with those constraints, would be:
1) Wrap the click target in a form, and set the id to a hidden value. On click, just post the form. This will require a page refresh, but since it's a POST, won't muck up the url.
2) Set the id in a cookie, force a page refresh, read the id on the server and unset it. This will obviously also require a page refresh, but won't encode anything in the url.
3) Use an invisible iFrame to load a url with the param of interest. This won't require a refresh and the url can be anything, since the user will never see it.
If a page refresh/change is fine, the form route is probably best. If you don't want the page to refresh though, an xhr request is clearly the best solution. It's really simple to do, but an iFrame solution would be a hack that probably meets your needs too.
I am assuming you don't want to show the ID to the user but you need the element ID to hit the server.
You could use a custom request header, but that would require an AJAX approach. Here's a sketch with JQuery
$("a.sends_element_id").click(function(e){
e.preventDefault();
$.ajax({
url: $(e.target).attr("href"),
type: "GET",
beforeSend: function(xhr){xhr.setRequestHeader('X-Element-ID', $(e.target).attr("id");},
success: function(result) {
// Do something here to display the page
// Eg. http://stackoverflow.com/questions/824349/modify-the-url-without-reloading-the-page
}
});

rails 3: (probably ajax question) need embeddable a banner on a html page that pulls a different 'joke' from our app every N seconds

I've never done ajax stuff myself, and this seems like an ideal feature to add to my app to learn how to do it...
My app maintains a database of jokes.
I'd like to provide a simple way for anyone to add a small banner to the html on their webpage that will display a new joke every N seconds.
It seems the two approaches are:
1) iframe where the url/view hit by the iframe has a meta refresh tag and randomly pulls a joke each time the url is hit. But iframes can resize to fit content, and I'm not sure if browsers will refresh the contents of the iframe.
2) the right way ... ajax. But I have no idea if this is a "big" or "trivial" job for a rails 3 app, and no idea where to get started.
Any pointers on doing this would be deeply appreciated!
I'll use jQuery for this example but the overall technique should work pretty much the same with any other AJAX framework.
In your JavaScript, you'll want to use $.ajax to grab a new quote from your server and setTimeout to get periodic updates; something like this:
var n_seconds = 5; // Or whatever you want.
var timer = null;
function replace_quote() {
// Do a $.ajax call to your server.
$.ajax({
url: '/some/route',
type: 'get',
dateType: 'htm;',
success: function(data) {
// Replace the quote with the new one.
$('#quote-container').html(data);
// And restart the timer.
timer = setTimeout(replace_quote, 1000 * n_seconds);
}
});
}
replace_quote();
If you start out with an empty quote box then you can simply call replace_quote() to give it an initial value through your AJAX call.
You could also use setInterval to call your quote replacer. Then you wouldn't need to manually restart the timer with the setTimeout call but you would run the risk our updates fighting each other if an AJAX call takes longer than n_seconds.
If you still want to provide a link for updating the quote then bind the link to a JavaScript function something like this:
function manually_replace() {
clearTimeout(timer);
replace_quote();
}
Calling clearTimeout will, effectively, reset the timer when they change the quote themselves.
Then, in your Rails app, you'd add a route for /some/route and the controller would simply grab a random quote from your database and then use render :partial => 'quote' to send back just the HTML snippet for the quote without all the usual layout wrapping.
Handling AJAX requests in Rails (or any other framework) is pretty much the same as handling any other request, the only difference is that you won't send back a full page, you just send back a little piece of HTML or a blob of JSON (or XML) for the client to process and render. Hence the size difference between the client-side and server-side outlines above.

Resources