Kirby CMS: how to return Blocks as HTML? - kirby

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

Related

Posting to a web form and catching results from JavaScript code

How would I go about achieving the following
I have some HTML data triggered from an Evernote new note action
I need to pass this HTML string to a website via an http post with form variables
I then need to catch the resulting web page text in a variable to use in my next action.
For clarity the website simply takes some HTML and converts it to markdown passing it back out as the body of the resulting page
Regards in advance
Dan
Sweet! So I've got this working. In my example, text is some html I pulled out of a dummy previous step:
The output is:
Which has the markdown as a key. If you want to tweak other data based on the api params, you can do that as GET params below html
​Let me know if you've got any other questions!

How to accomplish this MVC layout

Being relatively new to MVC I have been struggling for the past several weeks getting my layout to work.
I have managed to get myself really twisted into knots. So instead of trying to explain and unravel my mess perhaps instead someone could explain how I would accomplish the following at a high level.
_Layout this would have all the css js etc. It would also have basic structure.
Of course HTML tags not allowed in code block....each render is in a div.
#RenderPartial(Header)</div>
#RenderBody()</div>
#RenderPartial(Footer)</div>
RenderBody is Index.cshtml and it would be broken into three pieces
#
#Html.Partial(NavMenu, model)</div>
#Html.Partial(SubNavMenu, model)</div>
#Html.Partial(MainContent, model)</div>
I have this basic layout and it looks fine until you click one of the menu items.
The menu items render as:
<a class="k-link" href="/stuffroute">Stuff</a>
That route goes to a controller that returns a view and that navigates away from the above arrangement in Index.cshtml. So I end up with the header, footer, and subdash nav....
So the question is...
How do I route / orchestrate my layout to not lose the differing pieces?
Partials don't do anything for you here. You're essentially asking about how to create SPA (single page application), although in this case your application will have other pages, it's just that the index view will act like a SPA.
That requires JavaScript, specifically AJAX, to make requests to endpoints that will return HTML fragments you can use to replace portions of the DOM with. For example, clicking "Stuff 1" causes an AJAX request to be made to the URL that routes to FooController.GetSubNav([stuff identifier]). That action then would use what was passed to it to retrieve the correct sub-nav and return a partial view that renders that sub-nav. Your AJAX callback will then take this response, select a portion of the DOM (specifically the parent of the sub-nav) and insert the new HTML as its innerHTML.
If you're going to be doing a lot of this, you'll want to make use of some client-side MVC-style JavaScript library, like Angular for example. These make it trivial to wire everything up.

Json vs html.erb in ruby

My project is on ruby on rails.
I have one of ruby api returns json.jbuilder.
But I want that my api should not return json , it will display html.erb file.
Is anybody can help me???
First of all, it is not recommended to forcefully respond with html template for a json request or vice versa.
I hope you have enough reasons for this which are best known to you.
Anyways, if you want to forcefully process a particular request as html, you can append .html in the end of request url.
e.g. If you want to process index action of users controller whose url is
http://localhost:3000/users
To achieve it
Call controller action with url
http://localhost:3000/users.html, controller will treat request as html and it will respond with html(you will need to have a html template for your controller action).
Similarly if you want to respond json for any request, append .json to the request url,
http://localhost:3000/users.json
controller will treat request as json and it will respond with json(you will need to have a json template for your controller action).

Rendering a response from a URL to RSS format

I am creating a controller that receives certain parameters from an application, then accesses a hard coded URL. Upon receiving a response from the URL my controller should render this response to RSS format.
In doing this I decided to use XPath to sort of create the xml tags, I then used StringBuilder to append these tags and then rendered the result as text. This is able to show on the browser just how I want it.
However when I try to view the page source it does not show any tags or headers, it just shows it as normal text on a page. I need help with what to do so that the headers and tags can appear in the page source.
I would suggest having your controller send the data as JSON, and then creating a template that renders the JSON as rss2/xml. For best results, make your JSON structure easy to loop over to create the RSS feed by looking at how feeds are organized.
Here's the rss2 spec
make sure that this line is at the top of your file with NO leading spaces
<?xml version="1.0"?>
Also make sure your content is served with "text/xml" as its content-type. In php, one would set this as such:
header('Content-Type: text/xml');
See http://www.electrictoolbox.com/rss-php-content-type/

Rails take base64

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

Resources