Reputation: 59
What I'm trying to do in PHP is load a file which contains php style variables, and replace them with the contents of the variable. Here is my expample code which does not function how I intend it to.
module.html
<div class="module">
$moduleText
</div>
index.php
<?php
$moduleText = "Hello, World!";
$module = file_get_contents ( "module.html" );
echo $module;
?>
index.php Output
<div class="module">
$moduleText
</div>
index.php Desired Output
<div class="module">
Hello, World!
</div>
Is there an easy way in PHP to get this desired output?? I'm building a CMS and this would make module inclusion a snap for me. Any help, snarky comments, or points in the right direction are greatly appreciated!!
Upvotes: 3
Views: 1330
Reputation: 1192
Yes it is possible as of today, making all template libraries a thing of the past.
For anyone searching for exactly this problem like I was:
Load file as string which contains variable definitions
The answer is quite simple:
<?php echo $myvar ?>
inside your fileI'll give an example with CSRF protection(!)
form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Form Template</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/5.1.1/bootstrap-social.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-xs-offset-0 col-sm-8 col-sm-offset-2">
<form method="POST" action="" novalidate="novalidate">
<div class="form-group">
<label for="email" class="control-label">Email</label>
<div class="input-group">
<label for="email" class="input-group-addon" aria-hidden="true"><i class="fa fa-at fa-lg"></i></label>
<input type="text" class="form-control" id="email" name="email" value="" required="" title="Please enter your email" placeholder="[email protected]">
</div>
<span class="error help-block">Not acceptable domain</span>
</div>
<div class="form-group">
<label for="password" class="control-label">Password</label>
<div class="input-group">
<label for="password" class="input-group-addon" aria-hidden="true"><i class="fa fa-lock fa-lg"></i></label>
<input type="password" class="form-control" id="password" name="password" value="" required="" title="Please enter your password">
</div>
<span class="error help-block">Wrong password</span>
<p><a href="/auth/newpass">Forgot password?</a></p>
</div>
<input type='hidden' name='csrf' value="<?php echo $arg[0] ?>">
<button class="btn btn-primary btn-block">Sign in</button>
<button class="btn btn-default btn-block">Cancel</button>
</form>
</div>
</div>
</div>
</body>
</html>
Of special interest is line
<input type='hidden' name='csrf' value="<?php echo $arg[0] ?>">
template.php
session_start();
$csrf = $_SESSION['csrf']; //session stores the value
$arg = array($csrf);
ob_start();
include './form.html';
$include = ob_get_contents();
ob_end_clean();
// do whatever you want with $include
echo $include; // the page is rendered correctly!
We achived:
$arg[n]
to assist them)superior approach than the already there php's core function output_add_rewrite_var() as
3.1. it's meant to solve a different problem
3.2. it uses one buffer whereas here we control the buffer and avoid the delay that the one buffer introduces when echoing the page.
Hope that helps someone looking for this.
Upvotes: 0
Reputation: 59
I ended up creating a template system. The code should work if you copy and paste it while following my sample directory structure.
Let me know if you have any questions or alternative ways of doing this. I'm always open to improvements. :)
Sample Directory Structure:
- templates
---- index.html
---- module.html
- includes
---- functions.php
- index.php
index.html:
<b>${myVariable}</b>
<div>
${module}
</div>
module.html:
<b>${foo}</b>
<i>${bar}</i>
functions.php:
<?php
function getTemplate($file, $hooks){
//Read our template in as a string.
$template = file_get_contents($file);
$keys = array();
$data = array();
foreach($hooks as $key => $value){
array_push($keys, '${'. $key .'}');
array_push($data, $value );
}
//Replace all of the variables with the variable
//values.
$template = str_replace($keys, $data, $template);
return $template;
}
?>
index.php:
<?php
require_once('includes/functions.php');
/*
* Load Modules First so we can get the
* contents as a string and include that string
* into another template represented by a
* variable in the template such as
* ${module}
*/
$moduleHooks = array(
'foo' => 'Oh fooey',
'bar' => 'Chocolate Bar'
);
$moduleTemplate= 'templates/module.html';
$moduleText = getTemplate($moduleTemplate, $moduleHooks);
/*
* Load the module you want to display. Be sure
* to set the contents of the contents to a hook
* in the module that we will display
*/
$indexHooks = array(
'myVariable' => 'Index Variable',
'module' => $moduleText
);
$indexTemplate = 'templates/index.html';
$indexText = getTemplate($indexTemplate, $indexHooks);
/*
* Finally Display the page
*/
echo $indexText;
?>
Output:
<b>Index Variable</b>
<div>
<b>Oh fooey</b><i>Chocolate Bar</i>
</div>
The problem that I had with using includes was that when I used say "include module.html;", I couldn't decide where to put that inside of a index.html file unless I turned index.html into a php file.
Upvotes: 0
Reputation: 2228
You can do this using Heredoc string
Let me give you a example:
index.php
<?php
$moduleText = "Hello, World!";
include "module.php";
echo $module;
?>
module.php
<?php
$module = <<<EOD
<div class="module">
$moduleText
</div>
EOD;
?>
You can do this in any loop and it will behave as expected.
Hope this helps!
Upvotes: 2