Using Twig to separate design stuff from index.php - php

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.

Related

Joomla Component: include/require php in View

this is my first time making a component for Joomla 3.
I'm trying to convert a php website to a component.
Almost every view of my php website is built this way:
Header
Sidebar
Navigation bar
Actual content
Footer
Scripts
So basically it looks like this:
A view from php website
<?php require_once('includes/header.php'); ?>
<body>
<div">
<?php require_once('includes/sidebar.php') ?>
<div>
<?php require_once('includes/navbar.php') ?>
</div>
<div>
<!-- Content or something -->
</div>
<?php require_once('includes/footer.php') ?>
</div>
<?php require_once('includes/scripts.php') ?>
<script>
</script>
</body>
</html>
But in Joomla this is not possible. If I try to include or require a php file like above it just doesn't work.
View in component looks like this:
com_component
../views
../tmpl
default.php
view.html.php
../includes
header.php
footer.php
sidebar.php
scripts.php
navbar.php
Default.php is supposed to show a dashboard on the frontend.
This is what I'm trying to do in default.php:
Default.php
<?php include_once('../../includes/header.php') ?>
<body>
<?php include_once('../../includes/sidebar.php') ?>
<?php include_once('../../includes/navbar.php') ?>
<!-- Some content-->
<?php include_once('../../includes/footer.php') ?>
<!-- etc -->
What I've done
I've found some JDocument and JHTML functions which can add stylesheets and javascript to the template. But that is not what I'm looking for.
I used Joomla's addCustomTag function but it only shows a commented php line in the template.
Tried to make a String of it and passed it through a variable.
Questions
Is it possible to include php files in a template (default.php)?
If not, is there any other way to do it?
If yes, is that good practice in Joomla?
Thanks
To include files in the same directory as the given file, you can use:
include __DIR__ . '/../includes/header.php'
If you don't use DIR the current path is related to the main page (index.php in the site root) and not to the layout (default.php).
A more Joomla compatible solution is to put all your "sub-layouts" in the same folder with a conventional naming like this:
com_component/
views/
myview/
view.html.php
tmpl/
default.php
default_header.php
default_footer.php
....
Then you can use in your main layout the following code:
echo $this->loadTemplate('header');
...
echo $this->loadTemplate('footer');
You don't need a component to do any of this. I mean you can
do this but it should only be as an intermediary step since Joomla is designed to make all this easier by having APIs to include modules which is basically what all your pieces are.
You'll notice that in the joomla template file there are places where module positions are loaded. These are things like menus, footers, sidebars etc.
Depending on what they are you should really make each of these subsections a module. In some cases you can probably use existing modules already in Joomla or make a "custom html" module if you are just loading some html. In other cases makin a joomla module is really easy, just a few files, and you can put your php code there, really to start you can put the whole thing in the tmpl/default.php for the module or you can split it between the helper and the layout.
You'll be much happier in the long run if you take advantage of using a CMS rather than fighting it.
Components are only for the "body" area, what you need to do is make a template and then the modules.

Codeigniter - Templating with separate templates

I wish to have a codeigniter application with 3 templates.
a template for displaying a login view, or an error view.
a template with header body navigation
a template with header body sidebar footer
now I can build the codeigniter application, but I can't find a simple template system to accomplish this task. There are many recommendations for libraries available, but they lack implementation details.
Suggestions and guidance would be appreciated.
You can user CodeIgniter Template.
http://williamsconcepts.com/ci/codeigniter/libraries/template/index.html
Download here the library and also you have a full documentation.
With this library, you can use more than one template, and you can manage it easy and separate in groups.
It's quite simple once you get your head around it.
You need to create a view file for each of the things you've listed above, so you'll want something like this (folder/file wise):
views/page-login.php
views/page-error.php
views/header.php
views/footer.php
Then from your controller you will load one of the page views.
Within the page view you can then load the elements you require, so header and footer with the page specific code between them.
So for example your login page could be:
<?php $this->load->view('header'); ?>
<h1>Login</h1>
<p>Please login to my website.</p>
<?php $this->load->view('footer'); ?>
This is fairly simple.
A quick example:
In your controller you can put
//a test variable
$data["foo"] = 'bar';
$data["page"] = 'a_page'; // this will make sure it loads the views/pages/a_page.php in your template
$this->load->view('templates/login',$data);
And in your views/template/login.php you can put:
<!-- your login template html -->
<html>
...
<!-- include the view you want inside your login template -->
<?php $this->load->view('pages/'.$page);?><!-- As you can see it loads /views/pages/a_page.php -->
<?php echo $foo;?> //This will echo Bar
</html>
or:
<?php $this->load->view('template/login_header');?>
<?php $this->load->view('pages/'.$page);?>
<?php $this->load->view('template/login_footer');?>
views/pages/a_page.php will also know $foo.
This loads another view (views/pages/a_page.php) in your template.
This way you can create all the templates you want, and include your view in those templates.
TIP: Handling headers & footers this way get's unmanageable pretty quickly. And it's still better to use template libraries. Try Phil sturgeon's library

CodeIgniter "Template" system

Whenever I start a new project I find myself remaking and rethinking my self made template library. I use some influences from dom manipulation, but don't want to make too much functions so that it still loads fast.
This is how my current template system looks like:
This is a layout file:
<body>
<div id="content">
<block:content>This is a default text</block:content>
</div>
<div id="sidebar">
<widget:advertisement type="wide" />
<block:sidebar this_param="is_passed_on" />
</div>
</body>
As you can see I made 2 sort of "extra" tags that will be replaced when eventually publishing the template. I load this layout like this:
$this->template->load("layout");
I then can manipulate the block tags like this:
$this->template->content = "I'm overwriting the default text";
$this->template->content->prepend("I forgot something");
$this->template->sidebar->view("viewfile_1", array(/*data*/));
$this->template->sidebar->view("viewfile_2", array(/*data*/));
I can set text manually, I can load multiple views into 1 block, I can use a few dom-like manipulating functions like prepend, append, ...
I can even extend the template with more layout options like:
$this->template->content->extend("2columns");
This layout file might look like:
<div><block:left/></div>
<div><block:right/></div>
So that instead of the content block I now have an extra left and right block to put content in.
I have also created a widget tag that loads the specific widget class (/widgets/advertisement in this case). The optional parameters added in the tags are passed on to the views files and/or widget display function together with the direct passed data array.
In short, this is how my system now works. I haven't really found other systems like this to get inspiration from. Could you guys give me advice on anything so I can put together one decent system that I can keep using?
My approach is:
Create main layouts for each page type on a layouts/ folder (think Wordpress layouts for home, archive, single post, single page)
Create common bits of interface in a common/ folder (think header, footer, sidebar, widget_XX, widget_YY)
Use Phil Sturgeon's Template Library (or Spark!) to handle the views.
On each controller I load all the data needed for rendering in $this->data and I pass that object to the view
Hope this helps! Good luck.

How is duplicate HTML represented in your codebase, in a non-duplicate way?

Most HTML in a large website is duplicated across pages (the header, footer, navigation menus, etc.). How do you design your code so that all this duplicate HTML is not actually duplicated in your code? For example, if I want to change my navigation links from a <ul> to a <ol>, I'd like to make that change in just one file.
Here's how I've seen one particular codebase handle this problem. The code for every page looks like this:
print_top_html();
/* all the code/HTML for this particular page */
print_bottom_html();
But I feel uncomfortable with this approach (partially because opening tags aren't in the same file as their closing tags).
Is there a better way?
I mostly work with PHP sites, but I'd be interested in hearing solutions for other languages (I'm not sure if this question is language-agnostic).
I'm not a php programmer, but I know we can use a templating system called Smarty that it works with templates(views), something like asp.net mvc does with Razor.
look here http://www.smarty.net/
One solution at least in the case of PHP (and other programming languages) is templates. Instead of having two functions like you have above it would instead be a mix of HTML and PHP like this.
<html>
<head>
<title><?php print $page_title ?></title>
<?php print $styles ?>
<?php print $scripts ?>
</head>
<body>
<div id="nav">
<?php print $nav ?>
</div>
<div id="content">
<?php print $content ?>
</div>
</body>
</html>
Each variable within this template would contain HTML that was produced by another template, HTML produced by a function, or also content from a database. There are a number of PHP template engines which operate in more or less this manner.
You create a template for HTML that you would generally use over and over again. Then to use it would be something like this.
<?php
$vars['nav'] = _generate_nav();
$vars['content'] = "This is the page content."
extract($vars); // Extracts variables from an array, see php.net docs
include 'page_template.php'; // Or whatever you want to name your template
It's a pretty flexible way of doing things and one which a lot of frameworks and content management systems use.
Here's a really, really simplified version of a common method.
layout.php
<html>
<body>
<?php echo $content; ?>
</body>
</html>
Then
whatever_page.php
<?php
$content = "Hello World";
include( 'layout.php' );
Sounds like you need to use include() or require()
<?php
include("header.inc.php");
output html code for page
include("footer.inc.php");
?>
The header and footer files can hold all the common HTML for the site.
You asked for how other languages handle this, and I didn't see anything other than PHP, so I encourage you to check out Rails. Rails convention is elegant, and reflects #codeincarnate 's version in PHP.
In the MVC framework, the current view is rendered inside of a controller-specific layout file that encapsulates the current method's corresponding view. It uses a "yield" method to identify a section where view content should be inserted. A common layout file looks like this:
<html>
<head>
<% #stylesheet and js includes %>
<body>
<div id="header">Header content, menus, etc…</div>
<%= yield %>
<div id="footer">Footer content</div>
</body>
</html>
This enables the application to have a different look and feel or different navigation based on the controller. In practice, I haven't used different layout files for each controller, but instead rely on the default layout, which is named "application".
However, let's say you had a company website, with separate controllers for "information", "blog", and "admin". You could then change the navigation for each in a clean and unobtrusive manner by handling the different layout views in their respective layout files that correspond to their controllers.
You can always set a custom layout in the controller method by stating:
render :layout => 'custom_layout'
There are also great helper methods built into Rails so you don't have to rely on $global variables in PHP to ensure your CSS and Javascript paths are correct depending on your development environment (dev, staging, prod…). The most common are:
#looks in public/stylesheets and assumes it's a css file
stylesheet_link_tag "filename_without_extension"
#looks in public/javascripts and assumes it's a js file
javascript_include_tag "jquery"
Of course, each of these sections could be expounded upon in much greater detail and this is just brushing the surface. Check out the following for more detail:
http://guides.rubyonrails.org/layouts_and_rendering.html
What you suggested works OK. As long as print_top_html and print_bottom_html stay in sync (and you can use automated tests to check this), then you never need to worry about them again, leaving you to focus on the real content of the site -- the stuff in the middle.
Alternatively, you can combine print_top_html and print_bottom_html into a single call, and send it HTML code (or a callback) to place in the middle.
I use the partials system of Zend_View (very similar to Rails). A partial is essentially a small HTML template that has its own variable scope. It can be called from inside views like:
<?php echo $this->partial('my_partial.phtml', array( 'var1' => $myvar ));
The variables that get passed into the construct get bound to local variables inside the partial itself. Very handy for re-use.
You can also render a partial from inside normal code, if you're writing a helper object where you have more complex logic than you'd normally feel comfortable putting in a view.
public function helperFunction()
{
// complex logic here
$html = $this->getView()->partial('my_partial.phtml', array('var1' => $myvar ));
return $html;
}
Then in your view
<?php echo $this->myHelper()->helperFunction(); ?>

Zend organization question

So I had a question on general organization of code for the Zend framework with regard to the layout.
My layout is basically this:
(LAYOUT.PHTML)
<div id='header'>
<?= $this->Layout()->header ?>
</div>
<div id='main'>
<?= $this->Layout()->main ?>
</div>
<div id='footer'>
<?= $this->Layout()->footer ?>
</div>
and so on and so forth. Now, in order to keep my code in my header separate from the code of my main and the code of my footer, I've created a folder for my view that holds header.phtml, main.phtml, footer.phtml. I then use this code to assign the content of header.phtml into $this->layout()->header:
(INDEX.PHTML)
$this->Layout()->header = file_get_contents('index/header.phtml');
$this->Layout()->main = file_get_contents('index/main.phtml');
$this->Layout()->footer = file_get_contents('index/footer.phtml');
That was working great, but I've hit a point where I don't want main to be static HTML anymore. I would like to be able to insert some values with PHP. So in my Controller in indexAction, I want to be able to load from my database and put values into index/main.phtml. Is there a way to do this without restructuring my site?
If not is there a way to do it so that I can have:
The ability to put code into different sections of my layout, such as Layout()->header, Layout->footer.
Separate these pieces into different files, so that they're easy to find and organize, like my index/footer.phtml, index/main.phtml etc.
Not have to put that code into quotes unnecessarily to turn it into a string to pass it to Layout()->header etc.
Thank you guys so much for your help.
-Ethan
Here is an idea:
Assign layout()->header the filename instead of the contents.
Put your code in this file
In your layout file, include() or require() the layout->header().
Since your layout headers/footers are now parsed, you can use them just like a view.
The ->header in $this->layout()->header is response segment. You can render parts of response using $this->_helper->viewRenderer->setResponseSegment('header'); in an action.
If you use
$this->layout()->header = $this->render('index/header.phtml');
It will even use the view, therefore keeping all your variables defined when rendering the header.
I would suggest using something like
<?php echo ($header = $this->layout()->header)?
$header : $this->render('headerDefault.phtml'); ?>
in your layout file - it will render a default header from the layout folder if the view script doesn't override it.
Have you tried looking at view helpers. They are a way of structuring view logic into reusable and modular code. In this case you would use a view helper to generate each of your required segments. So your example view script would look like
$this->Layout()->header = $this->header();
$this->Layout()->main = $this->main();
$this->Layout()->footer = $this->footer();
The benefit of using view helpers over include and require statements is that all of the file handling and name resolution is handled by the framework. The manual has more information on how to set up the paths and usage examples etc.
helpers are good. Another option is like the above, putting filenames in header/footer - put the template names and use $this->render($this->layout()->header)), etc etc. This is just like the include/require above, but more consistent.

Categories