How AJAX calls work with TWIG - php

I am trying to understand how Twig can load a template through AJAX.
From their website, it is clear how to load a template (http://twig.sensiolabs.org/doc/api.html)
echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here'));
But how would this work for an AJAX call? How would you tell Twig that you want to 'render' something that is only a part of index.html ... and not reload the entire page? I looked at Twig's sole Ajax example (http://twig.sensiolabs.org/doc/recipes.html), but this doesn't explain how Twig knows what part of the page you want to change. Assuming your Ajax call results in page content updates. I just need a simple example of this, something more than what is on Twig's recipe page.

Directly in the template:
{% if app.request.isXmlHttpRequest() %}
// code if ajax request
{% else %}
// code if not ajax request
{% endif %}

There are several ways to accomplish that :
1) Separate your index.html in several files like index.html and content.html.
Then use include function in index.html to include content.html.
Example :
if(isAjaxRequest()) //try to find the right function here
echo $twig->render('content.html', array('the' => 'variables', 'go' => 'here'))
else
echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here'));
Edit :
If you do your ajax request with jQuery for example :
$.get('yoururl', function(data) {
$('#divtoremplace').html(data);
});
2) Use the request.ajax boolean in your index.html
{% if request.ajax == false %}
<p>My header, not reloaded with ajax</p>
{% endif %}
<p>My content, reloaded with ajax</p>
{% if request.ajax == false %}
<p>Other content, not reloaded with ajax</p>
{% endif %}
Not sure about the second one, but this should do the trick accordind to the documentation. The best way is the first solution, separate your code.

Related

How do you render a component within a partial in OctoberCMS?

In OctoberCMS, I am creating a component. In the component's default.htm partial file (/acme/myplugin/components/mycomponent/default.htm) I can include any other registered component by doing:
{% component 'someComponentName' %}
However if I have the following code to handle an AJAX request:
public function onAjaxRequest()
{
return [
'#ajaxUpdate' => $this->renderPartial('#dates-partial'),
];
}
and in my dates-partial.htm file I put the same contents as in my default.htm file, the someComponentName component is not rendered. I also tried putting the following at the top of the file:
[someComponentName]
==
however this is outputted directly as text to the page.
How can I have renderPartial() render a partial containing a component?
Hi I tried your approach but seems its working for me. let me share howI did the things.
My Page
title = "compo-in-partial-in-ajax"
url = "/compo-partial-ajax"
layout = "default"
is_hidden = 0
[newCompo]
[newOne]
==
<!-- AJAX enabled form -->
<form data-request="onTest">
<!-- Action button -->
<button type="submit">Call Ajax</button>
</form>
<div id="ajaxUpdate">
Default content.
</div>
{% component 'newCompo' %}
I have added 2 component
newCompo <- which is used to render content on page. basically in its 'default.htm' I added {% component 'newOne' %} so I am rendering another component inside.
newOne <- this is component which we are going to render inside our partial.
this is my ajax handler
public function onTest() {
return ['#ajaxUpdate' => $this->renderPartial('#partial.htm')];
}
newCompo component's -> default.htm
{% component 'newOne' %}
newOne component's -> default.htm
<h1>Newone</h1>
Partial file which is inside components/newcompo -> partial.htm
<h4>partial</h4>
{% component 'newOne' %}
Output
Normal
After ajax Call

Symfony and data input

Currently I am working on a controller class which should be able to let a customer add an item to a table in a database and view these items (e.g. a movie).
I am using the following twig code:
{% extends 'base.html.twig' %}
{% block body %}
{% if movies|length == 0 %}
There are no movie items available. Add a movie here to get started.
{% elseif movies|length != 0 %}
These are the results: ...
{% endif %}
{% endblock %}
What is the best way to let a user/customer or whatever the case, add an item to the table that needs to be shown? Should I let a user fill a form on the exact same page as the overview template (I personally do not think this is good, as I want to keep purpose of each page seperated) or should I make a different template with a form where the user will be send to (though this takes redirection time, which some users might be getting annoyed by)? As you can see I am using an anchor tag on the word "here". How should I set-up the anchor tag if I am to use a different template for creating records in a table?
As the documentation of Symfony shows the following:
Home
The path says _welcome and I think it refers to the name of the route that points to a certain controller. Would it be best to use this path function and what would I need to add where it now says _welcome (or was I correct one sentence ago)? And why is there an underscore in the given example?
I am asking this question because when I worked with ASP.NET MVC, there was this method called ActionLink() and made me wonder if this is most common use of redirecting, since you could also just add the template file location to the anchor tag href attribute?
If the form to add a new item is small (one text field + one submit button), you could add the form in the same page.
For example :
{% extends 'base.html.twig' %}
{% block body %}
// display your form here
{% if movies|length == 0 %}
There are no movie items available.
{% elseif movies|length != 0 %}
These are the results: ...
{% endif %}
{% endblock %}
But actually it's up to you to decide if you want it to be displayed in the same page or not.
In the case you decide to redirect the user to a new template, especially for the form, you write the name of the route of the correspondant controller :
here
So the code of the controller will be executed and will redirect to the page of your form.
Concerning "_welcome", I don't know why they write it like this. This is more the way to name a layout file than a route name.

Header/navbar/footer elements not importing into new page

I'm using UserFrosting and so far I've been able to import all of the default elements into the home page. However, I've now added a second page but nothing happened when I copied the following code from the home page:
{% include 'common/components/head.html' %}
<rest of code>
{% include 'common/components/main-nav.html' %}
<rest of code>
{% include 'common/components/footer.html' %}
{% include 'common/components/jumbotron-links.html' %}
I then used the following php code:
<?php include("../userfrosting/templates/common/components/head.html"); ?>
Which seems to work but the page only shows this code found within the head.html file:
{% for item in includeCSS(page_group|default("common")) %} {% endfor %} {% for item in includeJSTop(page_group|default("common")) %} {% endfor %}
Which obviously is not very useful!
When I keep the home and page2.php file in the same folder (in localhost/userfrosting/templates/common) then I receive Error 404. When I move the file to the default UserFrosting home page directory (which the home.html file isn't actually in) in localhost/public, I get only the above code.
It seems like I'm missing something quite basic here but would appreciate some help. Thanks.
You are confusing PHP files and template files. UserFrosting uses a front controller pattern along with the Twig templating engine. So, you do not need a separate PHP file for each page. Instead, you should create a new template file for your page:
userfrosting/templates/common/page2.html
{% include 'common/components/head.html' %}
// DO NOT use PHP here - just Twig! See the Twig documentation: http://twig.sensiolabs.org/doc/templates.html
{% include 'common/components/main-nav.html' %}
// More Twig
{% include 'common/components/jumbotron-links.html' %}
{% include 'common/components/footer.html' %}
Then you need to link up a URL with this template. That is done in the controller, public/index.php, for example like this:
// Miscellaneous pages
$app->get('/page2/?', function () use ($app) {
$app->render('common/page2.html', [
'page' => [
'author' => $app->site->author,
'title' => "Page Deuce",
'description' => "This is the second page, aight?",
'alerts' => $app->alerts->getAndClearMessages()
]
]);
});
I highly recommend going through the tutorial on adding a new page: https://learn.userfrosting.com/building-pages
You can also learn more about MVC, Slim, and Twig here: https://learn.userfrosting.com/basics/overview
Feel free to join in chat if you are still having trouble.

How to realod specific blocks on Volt/Phalcon using ajax?

In my volt template:
<div class="container">
{% block conteudo %}
{% endblock %}
</div>
I want to load dynamically that block via ajax. All of my childs have block conteudo.
How i can do that?
Thanks for your help.
I think that you're mixing PHP with JavaScript.
So if you want to load something via AJAX just use empty DIV
<div class="container"></div>
then if you want to load something from server, ie part of view generated by Phalcon/Volt, create action that renders contents of that block.
In jQuery you can:
$( "#result" ).load( "some/conteudo", { maybeSome: "params" });
And you should have SomeController that have conteudoAction method that renders some/conteudo.volt view.
Your some/conteudo.volt should render only that part of view, ie:
<h3>{{ post.title }}</h3><p>{{ post.someThing }}</p>
Another way is to render you div.container contents by JavaScript with data obtained from serwer. To do that you could return JSON data from SomeController::contuendoAction and JavaScript part of your app will create HTML to your page.

Twig template not including block?

I'm looking to get started with Twig, but having a real headache getting the {% block %} to work at all - I feel there must be something very obvious I am missing.
My index.php loader looks as follows:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
require_once( "Twig/Autoloader.inc.php" );
Twig_Autoloader::register();
$twig = new Twig_Environment( new Twig_Loader_Filesystem("templates"));
$vars = array (
"user" => array(
"name" => "Joe Bloggs"
),
"title" => "My website"
);
$tpl = $twig->loadTemplate("index.html");
echo $tpl->render($vars);
?>
A simplified version of the index.html in /templates looks like this:
<!doctype html>
<html>
<body>
Hello World!
{% block navigation %}Test{% endblock %}
</body>
</html>
And the navigation.html in /templates looks something like this:
{% extends "index.html" %}
{% block navigation %}
<!-- Navigation -->
<nav>
Some navigation
</nav>
{% endblock %}
So far as I understood it, this should be a basic working example of the blocks feature. The other aspects of Twig seem to be working just fine for me, and no errors are being reported. Indeed, the page successfully prints "Test".
Should I be explicitly pointing to the navigation.html file somewhere, or does Twig automatically load all the files in the /templates folder?
The error: you're rendering your index template instead of the navigation one.
In the index template, the navigation block contains "Test", so your output is correct. If you render navigation.html, you'll get your html content from index.html and the navigation block from the navigation template (the only thing it overrides).
You always need to render the template you wish to output. One may be extended by many (for example, your layout may be extended by all your actions' templates).

Categories