Render template and array with handlebar - php

I have a template handlebar with php comment. I don't want the html result to include these comment php, and I can't use handlebar comment like {{! }}.
$template:
<?php
/**
* Template to show the Section on the front end.
*
* #uses array $options A collection
* #uses string $options['section_additional_classes'] A list of additional
*
* #uses array $dropzones A collection of widget dropzones.
* #uses string $dropzones['A'] A first dropzone.
*
* #package admin-panel
*/
?>
<script data-widget-template="frontend-section" type="text/x-handlebars-template">
<div class="row-fluid {{ options.section_additional_classes }}">
<div class="span12">
{{& dropzones.A }}
</div>
</div>
</script>
My code render with handlebar is (for example):
$hdlbars = new Handlebars_Engine();
$array_content_to_replace = array( 'dropzones' => array('A' => '<strong> Hello World!!</strong>'), 'options' => ('section_additional_classes') => 'class-example');
echo $hdlbars->render($template, array_content_to_replace );
the example before return html with php comment.

Why you can't use Handlebars template comments like {{! }}?
That indeed will solve your issue, just replace the <?php ?> tags from the comments and that code will stripped from the final template.

Related

Where is my twig template getting its variables?

I am trying to sort of reverse engineer to this twig template to get back to where the the variables are being set in the first place so I can add more variables. This is a Drupal8 project. The beginning of the twig template "node--course.html.twig" is seen below. Its where I see the variables being set.
{#
/**
* #file
* Default theme implementation to display a node.
*
* Available variables:
* - node: Full node entity.
* - id: The node ID.
* - bundle: The type of the node, for example, "page" or "article".
* - authorid: The user ID of the node author.
* - createdtime: Time the node was published formatted in Unix timestamp.
* - changedtime: Time the node was changed formatted in Unix timestamp.
* - label: The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: Themed creation date field.
* - author_name: Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
* - readmore: Flag for more state. Will be true if the teaser content of the
* node cannot hold the main body content.
* - logged_in: Flag for authenticated user status. Will be true when the
* current user is a logged-in member.
* - is_admin: Flag for admin user status. Will be true when the current user
* is an administrator.
*
* #see template_preprocess_node()
*
* #todo Remove the id attribute (or make it a class), because if that gets
* rendered twice on a page this is invalid CSS for example: two lists
* in different view modes.
*
* #ingroup themeable
*/
#}
{# {{ kint() }} #}
<article id="node-{{ node.id }}" {{ attributes }}>
{{node}}
{{ title_prefix }}
{% if not page %}
<h2{{ title_attributes }}>
{{ label }}
</h2>
{% endif %}
{{ title_suffix }}
{% if node.field_packaging.value == '1' %}
{% set image = content.field_image %}
{% set ce = content.field_tax_credit_hours %}
{% set goal = content.field_goal %}
{% set target_audience = content.field_audience %}
{% set objectives = content.field_objectives %}
{% set accreditation = content.field_accreditation %}
{% set disclosure = content.field_disclosure_statement %}
{# {% set references_old = content.field_references %} #}
{% set references = content.field_references_par %}
{% set appendix = content.field_appendix %}
{% set faculty = content.field_faculty %}
{% set related_courses = content.field_related_courses %}
{# set suggested_courses = content.field_suggested_courses #}
{% set additional = content.field_callout %}
{% set expiration = node.field_expiration.value %}
I have tried taking words that appear to be unique like
field_tax_credit_hours
And search the project to see maybe where its being set but it only appears in other twig files. I also looked at the whole page as a whole to see maybe I can search for where the output is coming from. For example they very start of my page begins with:
<!-- returning result -->
When I search that it points me to a php function called getResult()
public function getResult() {
if ($this->rowBase() == "") {
print "<!-- rowBase empty -->";
\Drupal\Core\Database\Database::setActiveConnection();
return false;
}
print "<!-- returning result -->";
$result = $this->connection->query($this->rowBase())->fetchAll();
\Drupal\Core\Database\Database::setActiveConnection();
return $result;
}
searching for rowBase() i found this function:
public function rowBase() {
if (parent::accessCheck()) {
$sql = "SELECT * FROM learning_courseuser
WHERE idUser = " . $_SESSION['public_area_idst'] .
" AND idCourse = " . $this->ID. " ";
return $sql;
} else {
return "";
}
}
So it appears to not set the variables I need but instead returns the users info if the are logged in. So I am now stuck and don't really know where to go from here. I have been a PHP developer for a year or so and only did a team treehouse drupal course so it was very basic.
I noticed the page also returns this
<!-- BEGIN OUTPUT from 'themes/custom/site/templates/node--course.html.twig' -->
But searching for the string "BEGIN OUTPUT" returns nothing. So I don't know where to go from here.
It seems that the variables are coming from the "content" object but searching content in the project has WAY too many results to go through. Any ideas where to look would be fantastic.
UPDATE
I was asked to look into template_preprocess_node
and got this:
function site_preprocess_node(&$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node && $node->getType() == 'course') {
$noti = new FormaNotification();
print "HERE";
print_r($noti->getResult());
exit;
if ($noti->getResult()) {
$variables['signIn'] = "yes";
if ($noti->getFormaAdmin())
$variables['is_forma_admin'] = "yes";
else
$variables['is_forma_admin'] = "no";
} else {
$variables['signIn'] = "no";
$variables['is_forma_admin'] = "no";
}
$current_url = Url::fromRoute('<current>');
$variables['signURL'] = 'http://' . $_SERVER['HTTP_HOST'] . $current_url->toString();
if ($node->get('field_packaging')->getValue()[0]['value'] == '2') {
$variables['regis'] = true;
} else {
$reg = new FormaRegis();
$reg->setConnection('docebo');
$reg->setID($node->get('field_docebo_course_id')->getValue()[0]['value']);
$result = $reg->getResult();
if(!empty($result)) {
$variables['regis'] = true;
} else {
$variables['regis'] = false;
}
}
} // course
}
So looking at it, it appears to have some function of registration sign in and not the variables
The answer is into CMS.
The machine name starting with field_* usually is made when you create a new field into a content type on CMS.
Login into cms (/user) and search for structure-> content types -> (your content types) and then manage fields.
You should find it.

Yii 2 Exclude NavBar in Modal

In my index.php view, I have a button, once clicked, a modal will pop up:
<p>
<?= Html::button(
'Create New BizAdmin',
['value' => Url::to(['createbizadmin']),
'class' => 'btn btn-success',
'id' => 'modalButton'
]) ?>
<?php
Modal::begin(['id' => 'modal']);
echo "<div id='modalContent'></div>";
Modal::end();
?>
</p>
My modal file is createbizadmin.php where it has the following codes:
<?php
use yii\helpers\Html;
/* #var $this yii\web\View */
/* #var $model app\models\User */
$this->title = 'Create New Bizadmin';
?>
<div class="user-create">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_formbizadmin', [
'model1' => $model1,
'model2' => $model2,
]) ?>
</div>
My problem is this:
As you can see, the navbar looks horrible. The menu list seems to overflow outside the modal.
How do I get rid of the navbar inside my modal? I can't seem to find which part of creatbizadmin.php I should edit.
Any thoughts?
I'm guessing that you have a controller somewhere that is handling the url createbizadmin. I'm also guessing that inside that controller action you are rendering the view file like this;
$this->render("createbizadmin");
If so, then that is your problem. By calling a view file directly, Yii will apply default layouts to the view file. You have no control over how this happens from within the called view file, and all your menus etc will be rendered.
To get around this you will probably need to render a partial file. This rendres the file without applying layouts. So use;
$this->renderPartial("createbizadmin")
Alternatively, if the modal content is being generated as a result of an ajax call, you can respond from the controller with;
$this->renderAjax("createbizadmin")
This article seems to have a good explanation of how best to achieve this; Render a form in a modal popup

Symfony2/Datatable Bundle - error: set a datatable id in your action with "setDatatableId" using the id from in your view

I import the Bundle AliDatatableBundle on github following the doc step one by one except the part $ bin/vendor install in the installation because with Symfony2.6, there's no need to do this.
When I create the function in my controller, and the rendering in my twig, I have this error:
An exception has been thrown during the rendering of a template ("No
instance found for datatable, you should set a datatable id in your
action with "setDatatableId" using the id from your view ") in
MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig at
line 37.
Here's the code for the controller:
/**
* set datatable configs
*
* #return \Ali\DatatableBundle\Util\Datatable
*/
private function _datatable()
{
$controller_instance = $this;
return $this->get('datatable')
->setDatatableId('batiments')
//->setEntity("MySpaceDatabaseBundle:Batiments", "b")
// replace "XXXMyBundle:Entity" by your entity
->setFields(
array(
"Nom" => 'b.nom',
// Declaration for fields:
"Reférence" => 'b.referencebatiment',
// "label" => "alias.field_attribute_for_dql"
"Ensembles" => 'b.ensembles',
"_identifier_" => 'b.id')
// you have to put the identifier field without label. Do not replace the "_identifier_"
)
//->setWhere(
// set your dql where statement
//'x.address = :address',
//array('address' => 'Paris')
//)
//->setOrder("x.created", "desc")
// it's also possible to set the default order
->setHasAction(true);
// you can disable action column from here by setting "false".
}
/**
* Grid action
* #return Response
*/
public function gridAction()
{
return $this->_datatable()->execute();
// call the "execute" method in your grid action
}
/**
* Lists all entities.
* #return Response
*/
public function indexAction()
{
$this->_datatable();
// call the datatable config initializer
return $this->render('MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig');
// replace "XXXMyBundle:Module:index.html.twig" by yours
}
And then the code for my twig:
{% extends "MySpaceWelcomeBundle::layout.html.twig" %}
{% block content %}
<div class="jumbotron">
<h4><u>Rechercher un bâtiment et ses affectations spécifiques:</u></h4>
<br>
<div>
{{ datatable({
'id' : 'batiments',
'js' : {
'sAjaxSource' : path('mySpace_formulaire_recherche_batiments')
}
})
}}
</div>
</div>
{% endblock %}
I really don't understand, someone could help me to fix this?
I have already clear the cache, install assets and took over again from the beginning the doc, I do not understand.
Thank you in advance.
It seems like everything was good. I can't see the problem here, if you followed the doc of aliBundle. Try using the Jquery datatable here, the installation is easier I think and better for your project if it's to manage your entities in Symfony.
If you have questions for Jquery DataTables, don't hesitate to ask, I'm using it for a Symfony project too.

laravel blade, how to append to a section

If you look to laravel official documentation http://laravel.com/docs/4.2/templates
It says that giving this layout:
<!-- Stored in app/views/layouts/master.blade.php -->
<html>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
</body>
</html>
Extended by this view
#extends('layouts.master')
#section('sidebar')
<p>This is appended to the master sidebar.</p>
#stop
#section('content')
<p>This is my body content.</p>
#stop
Will append to the section sidebar. But actually if you try is it doesn't append, it just override the content from the extended template.
I heard about others blade function like #append, #prepend, #parent... no one seems to work.
Beside, this example in the official doc which doesn't work, I find that the blade documentation is very poor. There's nothing about blade function like #parent for instance.
The example in the documentation from Laravel website does indeed seem to be flawed, but I think it's a markdown parsing problem on the website, the same docs on github show the correct code:
In any case #parent does indeed work. The example in the docs should look like this:
#extends('layouts.master')
#section('sidebar')
#parent
<p>This is appended to the master sidebar.</p>
#stop
#section('content')
<p>This is my body content.</p>
#stop
A quick look in the Illuminate/View/Factory.php confirms what #parent does:
/**
* Append content to a given section.
*
* #param string $section
* #param string $content
* #return void
*/
protected function extendSection($section, $content)
{
if (isset($this->sections[$section]))
{
$content = str_replace('#parent', $content, $this->sections[$section]);
}
$this->sections[$section] = $content;
}
You can simply use #append...
#extends('layouts.master')
#section('sidebar')
<p>This is appended to the master sidebar.</p>
#append
#section('content')
<p>This is my body content.</p>
#stop
See here.
To understand how this works...
The compileStatements() method in the BladeCompiler calls the method compileAppend(), as you can see here:
/**
* Compile Blade Statements that start with "#"
*
* #param string $value
* #return mixed
*/
protected function compileStatements($value)
{
$callback = function($match)
{
if (method_exists($this, $method = 'compile'.ucfirst($match[1])))
{
$match[0] = $this->$method(array_get($match, 3));
}
return isset($match[3]) ? $match[0] : $match[0].$match[2];
};
return preg_replace_callback('/\B#(\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value);
}
In turn, that inserts a call to appendSection() which looks like this:
/**
* Stop injecting content into a section and append it.
*
* #return string
*/
public function appendSection()
{
$last = array_pop($this->sectionStack);
if (isset($this->sections[$last]))
{
$this->sections[$last] .= ob_get_clean();
}
else
{
$this->sections[$last] = ob_get_clean();
}
return $last;
}
as mentioned before, I used #parent and it works fine for me. May be an example for extended title will helps:
master.blade.php
#section('title')
My Blog
#stop
<!doctype html>
<html>
<head>
#include('includes.head')
</head>
<body>
<div class="container-fluid">
<div id="main" class="row">
#yield('content')
</div>
</div>
</body>
</html>
includes/head.blade.php
<meta charset="utf-8">
<title>#yield('title')</title>
post.blade.php
#extends('master')
#section('title')
#parent
| {{$post->title }}
#stop
#section('content')
// Post Body here ..
#stop
Therefore, The Title will be rendered to be like this:
My Blog | My Post Title
Actually, this will render something like:
<title>
My Blog
| My Post Title
</title>
so you can use the section second parameter to set the values:
includes/head.blade.php
...
#section('title', 'My Blog')
...
post.blade.php
...
#section('title', '#parent | ' . $post->ar_name )
...
And this will render:
<title>My Blog | My Post Title</title>
So you will get rid of the lines inside the title,
Hope that's helps.
Note:
This is used for Laravel 5.2, Not quite sure but as I remember, it works for Laravel 4 too.

Is there a way to have a navigation entry with no link in zend navigation?

I'm sure my question is pretty straight forward, and I've been looking for an answer to this, but I can't seem to make it work. I want to do something like this:
<?xml version="1.0" encoding="UTF-8"?>
<configdata>
<dashboard>
<label>Dashboard</label>
<controller>dashboard</controller>
<action>index</action>
<module>global</module>
</dashboard>
<bills>
<label>Bills</label>
<pages>
<create-bill>
<label>Create New Bill</label>
<controller>bill</controller>
<action>create</action>
<module>global</module>
</create-bill>
</pages>
</bills>
</configdata>
Please note that in the <bills> section, I want to have a category with just a label, that way when I add styling later, I can hover over "Bills" and "Create New Bill" and other links will be shown, but clicking on "Bills" shouldn't do anything because it's just a category header.
I hope that makes sense.
You must specify a type for your page otherwise Zend_Navigation will throw an exception. In cases like yours I always use a Zend_Navigation_Page_Uri as page type and specify its uri to #. To apply this to your config file you could do this
<bills>
<label>Bills</label>
<uri>#</uri>
<pages>
<create-bill>
<label>Create New Bill</label>
<controller>bill</controller>
<action>create</action>
<module>global</module>
</create-bill>
</pages>
</bills>
The generated markup still contains a link but it will not point anywhere.
Moreover, since you need to bind some javascript to it in order to show the menu, you could even disable it by returning false in the click handler for that links.
In order to attach javascript callbacks (or some css) to that kind of link you may find useful to attach a class to those links. Within the same configuration file, you could with this code
<bills>
<label>Bills</label>
<uri>#</uri>
<class>fakelink</class>
<pages>
<create-bill>
<label>Create New Bill</label>
<controller>bill</controller>
<action>create</action>
<module>global</module>
</create-bill>
</pages>
</bills>
In this case the generated markup would be
<li class="fakelink>
Bills
<ul>submenu here</ul>
</li>
and you could easily select that kind of links with a javascript library. For example with jQuery you could do this:
$(function() { $('.fakelinks > a').click(function () { return false; }); });
There is actually another way to solve this.
You can set custom properties on all Zend_Navigation_Page just by defining extra configuration options in your xml/array/...
Then by using a dedicated partial to render your menu/breadcrumbs you can perfectly skip rendering the <a> tag or render a completely different markup based on these properties.
<!-- ... -->
<page1>
<label>Page 1</label>
<uri>page1</uri>
<link>false</link> <!-- Custom property -->
<pages>
<page1_1>
<label>Page 1.1</label>
<uri>page1/page1_1</uri>
</page1_1>
<page1_2>
<label>Page 1.2</label>
<uri>page1/page1_2</uri>
</page1_2>
<page1_3>
<label>Page 1.3</label>
<uri>page1/page1_3</uri>
</page1_3>
</pages>
</page1>
<!-- ... -->
Note: I'm using the breadcrumbs example here but most of the Navigation View_Helpers have a setPartial() method, including the menu helper.
Then in your view script or layout you just specify that your breadcrumbs helper needs to use a partial.
<?php
echo $this->navigation()->breadcrumbs()->setPartial('my_breadcrumbs.phtml');
And in your partial you loop over the pages in year breadcrumb trail and check the custom properties for each page.
<?php
foreach($this->pages as $page)
{
$properties = $page->getCustomProperties();
// Check if we need to render the link tag
if($properties['link'] !== false){
echo '<a href="' . $page->getHref() . '">';
}
// Render the label
echo $page->getLabel();
// And check if we need to render the closing tag
if($properties['link'] !== false){
echo '</a>';
}
}
Note: By using a partial you'll lose some default functionality of the Breadcrumb View_Helper like setLinkLast, setSeparator, ... but these shouldn't pose too much of a problem.
If you're happy for your category labels to be spans then just specifying an empty URI will do the job. Zend_View_Helper_Navigation_Menu::htmlify() is what renders a Zend_Navigation_Page:
/**
* Returns an HTML string containing an 'a' element for the given page if
* the page's href is not empty, and a 'span' element if it is empty
*
* Overrides {#link Zend_View_Helper_Navigation_Abstract::htmlify()}.
*
* #param Zend_Navigation_Page $page page to generate HTML for
* #return string HTML string for the given page
*/
public function htmlify(Zend_Navigation_Page $page)
Example output:
<ul class="navigation">
<li>
<span id="menu-staff">Staff</span>
<ul>
<li>
Book Holiday
</li>
<li>
View Booked and Remaining Holiday
</li>
</ul>
</li>
</ul>
I went about it in a different way:
nav:
User:
label: Account Services
uri: #fakeUri
Then in my template code:
<?php foreach ($navSettings as $navSetting): ?>
<?php if ('#fakeUri' === $navSetting->getUri()): ?>
<?php echo $navSetting->getLabel() ?>
<?php else: ?>
<a href="<?php echo $navSetting->getUri() ?>"><?php echo $navSetting->getLabel()) ?>
<?php endif ?>
<?php endforeach ?>
<page_bills>
<label>Bills</label>
<type>uri</type>
<pages>
</pages>
</page_bills>

Categories