I work on a Symfony 3 app which uses Twig for rendering. To make the code more readable and reusable, I need to split a screen in small parts, parts which could be used in other screens (for example a clock widget). At first it seems easy, I could use the include Twig method to include that part of code. The problem is that my clock uses some specific CSS and JS scripts to work.
What would be the best way to create a reusable components composed of HTML, CSS and JS ? Thx in advance !
There is no "Component" concept or approach in Twig, but still you can encapsulate CSS + HTML + JS code in one file and include it as an isolate piece of code:
<style>...</style> {# or use <link href="..."> #}
<div>...</div>
<script>...<script> {# or use <script src="..."> #}
However, probably Twig is not the correct tool to achieve it and you should look at some frontend framework (e.g. VueJS https://v2.vuejs.org/v2/guide/index.html) by passing the data through HTML attributes.
Probably you can use include passing your data to a specific partial component and render it dinamically.
Check it : https://twig.symfony.com/doc/3.x/tags/include.html
Related
i've started to code my own browsergame and heard about Twig PHP. I read some things in the documentation, but i didnt found any way to include this system completly into my source structure.
My php structure is like that:
The "index.php" in root directory includes the content-site, which i've got from the global $_GET[]
<?php
// doing some stuff ..
include($dir_path . DIRECTORY_SEPARATOR . htmlspecialchars($_GET['site']) . ".php");
?>
In this content-site(lets take for example: news.php) im using classes and doing some stuff.
After i got all information, i put them in an array for using them in Twig:
<?php
// doing some stuff ..
$array = returnOfMyFunctions(); // just for example!
$loader = new Twig_Loader_Filesystem('templateDir');
$twig = new Twig_Environment($loader);
$template = $twig->loadTemplate('news.html');
$template->display($array);
?>
Easier said:
index.php => include("news.php") => display the "news.html" template
My Goal:
I want to create an environment for designers, where they cant use PHP and Javascript (i can just filter it through Twig template). So javascript can be included through my index.php in the html header section(i have a function adding all the js files depending on my $_GET variable).
But here comes my problem:
The designers should edit my main page too. What i mean? Its for example my index.php(not the file itself, just the template!). Because in my index.php file im not just including all the content-sites, but also the header, the navigation and so on. So the real problem is here, how can i export the design stuff from my index.php to a template file.(Because they shouldn't have access to my index.php. But they should have the option to design my main page. Making div tags around my included content-site and positioning my navigation and so on. So my idea was about including just a Twig template in my index.php, where the designer can move the included content-site and design writing his own div tags like he wants to.
For example an index.html template file:
<div id="header"> {{ header }} </div> // INCLUDE the header
<div id="leftnavigation"> {{ left-navigation }} </div> // INCLUDE the left navigation
<div id="rightnavigation"> {{ right-navigation }} </div> // INCLUDE the right navigation
<div id="contentsite"> {{ content-site }} </div> // INCLUDE the content-site
<div id="footer"> {{ footer }} </div> // INCLUDE the footer
I've read in the Twig Documentation that i can include functions and its just easy, but i dont think i should execute a function in a template file, which includes the content-site.
$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('function_name', function () {
// including the content-site in which another Twig template is loaded. (for ex: news.html)
});
$twig->addFunction($function);
I've read in the documentation some stuff about inherit a child template, but it doesnt seem to be the solution too..
Or am I just thinking about nonsense stuff and should make some div tags in my index.php file and give the designers no access to my index.php file, but just to the css file where they can edit the div classes of my index.php file? Im not sure, if thats enough for a designer.
First, let me say that all of this is very messy. My personnal suggestion would be for you to use a framework, to cleanly separate your logic in controllers, and the views in a separate directory. This way your designers can do their magic without having to know anything about what the PHP is about.
About your concern about inheriting templates in TWIG, it is a very good practice to have. It allows to define on deferent layers the elements of your view. For example you have a base.html.twig layout where you put the navbar you want on all pages of your site. Then, you write another template that inherits from this base ({% extends 'base.html.twig' %}), and it will have all the elements you have defined in base. Realy powerful way to avoid duplicating HTML code.
So, to sum up, separate your code into different layers (use MVC pattern or n-tier structure) and use TWIG inheritance, and all of this should become a lot cleaner and easy to work with.
I'm using Laravel and all my templates are using Blade templating. There are a few parts of pages which need to be rendered both on the server side and by JavaScript. For these I'm using Mustache templates (with mustache-l4).
The problem is how to have Laravel render the templates, but also to include them in the page with the Mustache tags intact, for the JS to pick up.
For example, if I have a (simplified example) Blade template like this:
<html>
<head></head>
<body>
<h1>{{ $pageTitle }}</h1>
#include('partials/'.$partialName, array('some_text' => $pageText))
<script type="text/mustache">
#include('partials/'.$partialName)
</script>
</body>
</html>
which includes .mustache partials like this:
{{#some_text}}
<p>{{some_text}}</p>
{{/some_text}}
The Mustache partial is rendered on page load fine. BUT when it's included between the <script></script> tags I want it to be rendered verbatim. ie, the {{#some_text}} Mustache tags should be there in the rendered HTML. Then the JavaScript can read it in as a Mustache template.
I can see this might be possible by changing the tag delimiters on the server-side (Blade) templates but at this stage, with scores of Blade templates already working, I'd rather not.
I can't get my head round how to do this. Could I change the Mustache delimiters just for one of the times it's included, so it's only fully rendered then?
Another way would be to escape the tags with #
<div>#{{ $str }}</div>
<div>#{{"<a>Plain text</a>"}}</div>
will result in
<div>{{ $str }}</div>
<div>{{"<a>Plain text</a>"}}</div>
StackOverflow Answer
One way of doing this would be to change blade's content tag.
Like so :
Blade::setContentTags('[%', '%]');
So that {{}} tags will be considered as plain string.
For further information refer this snippet:
laravel-recipes
How would I put this in my cakephp default.ctp file?
Im pretty novice at cakephp as ive just started using it.
<script>
$(function()
{
$('#slider-id').codaSlider();
});
</script>
Thanks, in advance.
Although your question is too vague to answer in its current state, you should have a look at the JsHelper,especially Js->buffer(). This allows you to append script in your views and output them all at once in your layout.
http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#working-with-buffered-scripts
open the app/View/Layout/default.ctp file in your favorite code editor
add the following between your <head> and </head>:
<script>
$(function()
{
$('#slider-id').codaSlider();
});
</script></li>
In CakePHP 2.x there are now things called blocks, and blocks are just chunks of output stored in memory until they are fetched for output.
There use to be a $scripts_for_layout variable that you could put your script into, but now we use the $this->fetch('scripts'); to get any JavaScript needed for the Html.
There are a few ways to inject JavaScript into the scripts block using the HtmlHelper.
To add it to the block, and this can be done in Views or Layouts. Just run this code before you fetch the block.
$this->Html->scriptBlock("$('#slider-id').codaSlider();",array('inline'=>false));
To output the scripts in your layout is easy.
$this->fetch('scripts');
The advantage of this approach is you can add JavaScript from multiple places in CakePHP, but they will be outputted in the layout at the location you desire.
If I have 10 images, 2 javascript files, and 4 css files that need to be included inside a Ci view... How is the best way to call all the files? I've tried calling all the external files using $this->load->view('image1.png') and $this->load->view('style.css'). But it doesn't seem to work properly. Any ideas on how to better approach this problem?
You're not using the view method correctly there.
You typically assign one view and pass things like js and css to the template. This can vary depending on how you use the framework.
$this->load->view('path-to-view'); will look for a view in the view folder and not an arbitrary file.
You might look into this:
http://codeigniter.com/user_guide/helpers/html_helper.html#img
for loading images, though I personally think it's pointless to call a framework's method for a basic html element like an image.
There are cases when you would use multiple views, like views to be returned as strings - loops and such may need these - but that doesn't look like the case in your question.
Just in case though here's the view docs:
http://codeigniter.com/user_guide/general/views.html
To elaborate further, the general idea is to use the CI controller to handle the data for your page, pass the necessary template data to the template (like your js and css specific to this page) then assign the necessary data to the view and pass that view to the template. You may be wondering what I mean by template too, since out of box CI loads views progressively if you just call them sequentially.
in your controller you may pass the view an array of header info:
$data['css'] = array('some-path.css','another-path.css');
$this->load->view('your-view', $data);
so in your view that handles the header you might call something like this:
<head>
<?php foreach($css AS $c): ?>
<link rel="stylesheet" type="text/css" href="<?php echo $c; ?>">
<?php endforeach; ?>
</head>
Here's a fair link to CI templates:
How to Deal With Codeigniter Templates?
It's a versatile framework with many options for using it however you are most comfortable.
I'm using symfony 1.4, I wrote a piece of js code to use in a template, and I want to put it in a JS separated file because I'll use it many times in the code.
I added the JS to the template using:
<?php use_javascript('mi_js') ?>
This templates has some ajax calls that refresh zones of the view with renderPartial method. This new zones also use the JS code, so I need to add this code in the partial view.
But if add:
<?php use_javascript('mi_js') ?>
in the partial, then it doesn't work.
To get this work I have to put all the JS code in the partial, like:
<script type="text/javascript">/*<![CDATA[*/
$('.mi_class').click(function() {
var a = $(this).parent();
...
As I told I don't want to do this.
Any idea what can I do? Any template method to do this?
Thanks in advance.
Alejandro G.
The reason why you have to put the code in the partial is the following:
When you use use_javascript('mi_js') then the (path to the) JS file gets added to the sfResponse object. Then, when the templates get rendered, all the JS files get included into the layout file via get_javascripts().
But now as you only render the partial and send the results back via Ajax, the JS files get not included.
I suggest to put your code into a function and add it to the header of your HTML file. Then in the partials you call:
<script type="text/javascript">/*<![CDATA[*/
$('.mi_class').click(the_new_function())
(Maybe you have to define parameters, I don't know).
You can attach event handlers to future DOM elements via jQuery's live() method. Another way is to bind handlers directly after loading your partial.
How about adding the JS file in a normal way to the parent page that utilises the partial, instead of the partial itself.
If the partial is called in lots of places, I'd just add it to the application's or modules' view.yml file.