I make a new website for my company and i want to use smarty (v3.1.29) for it. Now the problem is that we store the code for all pages in our database (home, products, downloads, ...). Some pages contains PHP inline functions like:
<?php include("functions.php"); ?>
<p> Hello <?php echo printWorldInColor(); ?> </p>
In my template (.tpl) file I have a div-section to load the content from our database:
<html>
<body>
<div id="content">
{$content}
</div>
</body>
</html>
So my code looks like this afterwards:
<html>
<body>
<div id="content">
<?php include("functions.php"); ?>
<p> Hello <?php echo printWorldInColor(); ?> </p>
</div>
</body>
</html>
Is there a way that smarty processes the PHP-code before parsing it?
Hint: I dont want to edit my template file. I just want to parse the database content to my content-section of the website.
What i tried:
saved database-content into a string and replaced PHP-tags with smarty-PHP-tags, then assign it to the template
SmartyBC-Class
You can't do that in Smarty. Also running php code stored in the database sounds like a terrible idea. But if for some reason you have to go on with this nonsense (and considering that you can't use eval), you can try this:
Read the php code from the database.
Save to a temporal php file
Turn on output buffering with ob_start()
include the file you have created
assign the output to a variable with ob_get_clean()
assign the variable to the template
But if I was you, I would try to do the project in another way.
Related
I am using one header file for every page which will show the HTML head(which includes meta tags and other CSS links)
Here I have used everything as dynamic as if I like in the case of canonical tags I have used $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_HOST'] and all other links to CSS are also accessible even if it can be any file from any directory.
Now I want to create a one-time title meta tag & description tags like this will be my main file looks like
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $page_title; ?></title>
<meta name="description" content="<?php echo $page_content; ?>" />
//Other meta tags & linking to css & js files
</head>
<body>
// Content ........
</body>
</html>
Now here is the twist is that many people will say that just use
$page_title = "Here is the title of the specific page";
$page_content = "Here goes the long-form description describing the page of specific page";
Yes, this would have worked out if the pages were different and had the same place to put that all before including the header file.
But my index page looks like this let me explain it too. (Using Bulma as a framework)
<?php
require 'include/db_connect.php';
require 'include/header.php';
?>
<form name="submitform" method="POST">
<div class="columns is-multiline" id="wrapper">
<div class="column is-6-desktop is-12-tablet" id="main_content">
<div class="box">
<?php
if($country)
{
?>
<?php require 'inc/country.php'; ?>
<?php
}
else if($country && $state)
{
?>
<?php require 'inc/country_state.php' ?>
<?php
}
else if($country && $state && $district)
{
?>
<?php require 'inc/country_state_district.php'; ?>
<?php
}
else
{
?>
<?php require 'inc/other_than.php'; ?>
<?php
}
?>
</div>
</div>
</div>
</form>
<?php require 'footer.php'; ?>
</body>
</html>
The main point here is that I am using the dropdown button which gets auto-submitted using js that's not relevant here but from the top, I have just explained what is the structure of my code.
Now as you can see the if-else structure which includes other files that create dynamic pages but their code starts only from the body and not from the head directly so I am not able to add those title tags and descriptions.
Now how to add title & description tags uniquely to each of these pages.
Any solutions, please... Thanks in Advance
Like already written in the comments. You should define the vars ahead of require 'include/header.php'; or use an MVC structure.
If you still want to stay with the existing code ob_get_contents() might help you.
Use ob_start(); at the beginning to tell PHP to not print any output and instead write the output to a buffer.
You can then at a later point use ob_get_contents(); to fetch the output buffer and print it.
You have to search in the output buffer for an identifier like %page_title% then and replace it with the actual value before sending the output.
This may look like following:
echo str_replace(%page_title%, $page_title, ob_get_contents());
Still I'd rather suggest restructuring your code, as the solution with output buffer is slower, uses more memory and is poor to debug.
actually am working on a php website, and am finished with it, and I want to make a good style to my project, I found many templates and am interested to “one-page bootstrap templates”, i have downloaded ones and don't know how to use them, I want to put my php pages in one of them but I don't know how to do that.
if you are coding php without any framework and template engine you can combine php and html( here bootstrap template) like this :
<html>
<body class="container">
text
<?php if $list=true ?>
<ul>
...
<ul>
<?php endif ?>
</body>
<html>
How to structure view hierarchy without using blade? What are the pure php counterparts of blade directives (i,e #section, #extend , etc)?
Perhaps, something similar to <?php extend('foo') ?>
In Phalcon framework, while it has its own template engine (Volt) all of its template engine is also available in pure PHP syntax.
Since Blade directives just compile to normal PHP, it is technically possible to use the view structuring features without actually using Blade. I don't think it's very pretty though, and I personally would think twice about this decision.
You can find all the PHP code, Blade is compiled to, in this class:
Illuminate\View\Compilers\BladeCompiler
Here are some of them:
#section('content')
<?php $__env->startSection('content'); ?>
#endsection
<?php $__env->stopSection(); ?>
#extends('layout')
This is a bit a tricky one. Usually Blade compiles it and then adds it to a footer variable which is printed at the bottom. So instead of putting it at the top (like you would with #extends) you have to place this at the end of your view:
<?php echo $__env->make('layout', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>
#yield('content')
<?php echo $__env->yieldContent('content'); ?>
To put this in a pure PHP way you'll have to check out the storage/framework/cache/views and see what's happening there. Basically, is what Blade compiles to PHP code (instead of using # and with proper function calls).
One way I can think is:
In your template where you use yield:
<!-- template.php -->
<div class="container">
<!-- instead of using yield('container') -->
<?php echo "_yield:container"; ?>
</div>
In your file, instead of using section and stop
<!-- view.php -->
<!-- instead of using extend('template') -->
<?php $templatePath = 'template.php'; ?>
<?php $sections = []; ?>
<!-- instead of using section('container') -->
<?php $currentSectionName = 'container'; ob_start(); ?>
<p>This will be in my container div</p>
<!-- instead of using stop -->
<?php
// get the current html
$sections["_yield:".$currentSectionName] = ob_get_contents();
ob_end_clean();
ob_start();
require($templateName);
$template = ob_get_contents();
ob_end_clean();
echo str_replace($template,array_keys($sections),array_values($sections));
?>
Of course, this approach is simplistic at best. The code provided is not intended as a copy & paste solution, more like the concept.
Everything else is simple:
#foreach($arr as $k=>$v)
...
#endforeach
translates to
<?php foreach($arr as $k=>$v) : ?>
...
<?php endforeach; ?>
That's how it's exactly done by the BladeCompiler. The same is with if and while.
The pure PHP equivalent to Blade is to split your code in sections like header and footer (for example) and then use require in your page to blend those sections in the corresponding place.
<?php
require("template/header.php");
// Here goes the body code
require("template/footer.php");
?>
There is no pure PHP functions that i can think of, to extend a page from a main template, a you do using the yield directive.
Blade compiles into PHP every time and what it compiles is stored in to storage/framework/views/*
The following link is a list of all things blade can compile to, you should be able to extract some knowledge out of this:
https://github.com/illuminate/view/blob/master/Compilers/BladeCompiler.php
The general idea for most templating engine is that they structure your code like so:
if ($condition):
// do stuff
endif;
while ($condition):
// do stuff
endwhile;
foreach ($array as $key => $value):
// do stuff
endforeach;
For further reference, see https://secure.php.net/manual/en/control-structures.alternative-syntax.php
Neither of blade directives is a 'pure' PHP function. PHP functions cannot start with # and all blade directives do. In short, blade directives are shortcuts or synonyms to PHP built-in functions or control structures.
You are free to use any other template engine – it doesn't have to be Blade. Blade is built-in, but you are not locked to it. Just install a vendor package or make your own one, and return your HTML output with response, instead of using View facade.
I have such type of code in view, add.ctp file in Cake PHP.
<div id="container">
<div id="content">
------------------
</div>
<div id="sidebar">
----------------
</div>
</div>
Now in Layout, in default.ctp file, we access this code by this line.
<?php echo $this->fetch('content'); ?>
I have sidebar in each and every view file, and if I need some changes then I will go in each and every file and then change.
Now My Question is that, can I made a file in layout like sidebar.ctp or any thing else that I just call this file in my view. If I can, then how I will made such type of file.
You could do it with include or elements like this
<?php echo $this->element('sidebar'); ?>
With the element, you make the sidebar.ctp file in the View/Elements/ folder.
Check for more information: Cakephp 2 Elements
The other way is with include (not my choice, but another way to accomplish it)
<?php include('../View/Layouts/sidebar.ctp'); ?>
You can use elements and if the content in elements is dynamic you can use the blocks supported in latest version of cakephp.
http://book.cakephp.org/2.0/en/views.html
For most of my projects I make an administration interface, which has the same design for every project. The design of the header, the footer, the topbar, the leftmenu, the css, etc. are always the same. It is a pity to create the views every time; so I was thinking: maybe there would be a nice way to put the admin interface in my MVC library, as it is reused by every project?
But for the moment, in every single view I got code like the following:
<?php $this->_include('/includes/doctype.php'); ?>
<head>
<?php $this->_include('/includes/head.php'); ?>
<title>Some title</title>
</head>
<body>
<?php $this->_include('/includes/topbar.php'); ?>
<div id="page">
<?php $this->_include('/includes/header.php'); ?>
<?php $this->_include('/includes/leftmenu.php'); ?>
<div id="content" role="main">
<h1>Some title</h1>
<p>Blah blah blah.</p>
</div><!-- /#content -->
<?php $this->_include('/includes/footer.php'); ?>
</div><!-- /#page -->
</body>
</html>
Would it be a good idea to extract the custom content from the structure of the interface, and put that structure in my library somehow to make it reusable?
After that how will it be possible to customize the title and the actual menus?
I do this all the time. I have a custom header and footer file that are called at the start and end of every page.
<?PHP
Require("includes/header.php");
...
Require("includes/footer.php");
?>
The header provides a database handle, a datetime string and handles logon, priveleges, logging of pageviews etc.
The footer provides a standard HTML page but includes some systematised variables. It also generates the menu dynamically from the driving database then closes the database connection.
This way when I write code, I don't get mixed up in the HTML and any bugs are easy to find.
I like variables akin to:
$display_scripts - adds extra data in the head section.
$display_onload_scripts - adds onload scripts to body section.
$display_style_sheets - option to include link to additional stylesheets
$display_above_menu - will appear above the menubar. NOT recommended.
$display_below_menu - will appear immediately below the menubar.
$display_one_column - page contents when only one column is to be used
$display_left_column - page contents when two columns used. Left pane.
$display_right_column - page contents when two columns used. Right pane.
$display_footer - appears in footer division.
My main code then just has to generate the appropriate variable. Fundamentally, what you need to do is examine the source of a good age you have produced then replace the stuff you want to change with variables.
Here is a schematised version of the file I use (pseudocode) to give you an idea of how I do it.
// Code here generates the menu from database
// Code here genereates popup alert messages from other users
//permanent links to external style sheets go here.
//You can also select skins here.
<?PHP
echo $display_style_sheets;
echo "<title>".$display_page_title."</title>";
?>
<script type="text/javascript" src="JAVASCRIPT GOES HERE.js"></script>
</head>
<body <?PHP echo $display_onload_scripts;?> >
<div id="page_area" >
<div id="banner">
</div>
<?php
echo $display_above_menu;
if(!$hide_menu){echo $display_menu;} //Insert the menu variable here.
echo $display_below_menu;
?>
<div id="content_area">
<div id="inner_content">
<?PHP
if($display_number_of_columns==1)
{
echo "<div id='onecolumn'>".$display_one_column."</div>"; //I only use this one
}
if($display_number_of_columns==2)
{
echo "<div id='leftcolumn'>".$display_left_column."</div>"; //these are left for legacy support from before I got better at CSS.
echo "<div id='rightcolumn'>".$display_right_column."</div>";
}
echo "<div id='footer'>".$display_footer."</div>"; //just in case - I hardly use it.
echo $display_pop_box; //for user alert messages to other users
?>
</div>
</div>
</div>
<div id="logbox"> Automatic Logout statement</div> //this is called by JS to activate timeouts.
</body>
</html>
<?PHP
$mysqlidb->close();
?>
Sorry it's such a lot of code. The layout allows easy adaptation and makes it simple to find the offending variable if things are not going as expected. There are more elegant solutions but this works well for me and is very fast.