Dependencies with templates

Oh! Does site point have an inbuilt PM feature? How lovely. Thanks! I’ll edit my post now

Hello there. Sorry for my inability to reply earlier. Your function might be befitting for a single page application but in my case, I don’t have the luxury of simply buffering output of variables pre-known to me. I sometimes need unique user pages that would display their datas long after the process that brought about their page creation is done meaning my needs involve

  1. getting contents from a template, instead of swapping out placeholders.
  2. specifying an ID with which that page can grab associated data from the model for output.
  3. then write a fresh file with the string from step 2 above.

In fact I think my situation has spiralled out of the initial scope the thread was opened in. But, all the same, you can take a look at my next reply.

Hello there. Thank you very much for your reply. I eventually took a deeper look into templating and after being through a lot of links leading to both tutorials, opinions and helper frameworks regarding the topic, I’ve come to understand that the underlying principle for a valid or acceptable templating system is separating logic concerns from the view. I visited your twig links and discovered that the only advantage with using such frameworks is probably that it makes the view easier for non developers to read (as seen from here https://paulund.co.uk/php-template-system). Call me lazy, but the idea of learning a new syntax for simply templating is a huge turn off for me plus I don’t know what a non developer would be doing with my code in the first place.

Special reference to this http://code.tutsplus.com/tutorials/roll-your-own-templating-system-in-php--net-16596 and this https://www.smashingmagazine.com/2011/10/getting-started-with-php-templating/:
So we are on the same page, the idea on those links is for implementing templating on a one page scale (Please correct me if I’m wrong) much like how Angular.js works. However, in my case, like mentioned in my comment above, I need something a bit on a larger scale. Basically, I definitely need attachment of concerns since the variables on these pages are dynamic content being read from the server and are bound to change when a user updates his settings. I think this goes to say I can’t do without server code on that page (which is what I did on this thread before being condemned but let’s not go down that line).

That now brings me to http://platesphp.com/simple-example/ which seems to be what I’m looking for. I don’t seem to see much difference between what they’re doing on their site and what I’m doing in the snippet I posted in #28 except, I have database calls and theirs is wrapped in a nifty class that makes it look more refined (Again, please correct me and point out if I’m wrong. I’m neither arguing nor trying to prove I know all. I’m talking off my understanding so far).

So my new goal is to, in like manner, wrap my template engine (controller) and its associated components in a nifty class with the following steps outlined:

  1. The class is initialized with a primary key and its properties are populated (not from _POST but from my user classes’ construct) then sent to the model.
  2. Grab the template as a string and
    b. init the new page by running the template against the primary key like I did in #28.
    c. create the file using string from 2b

As I stated earlier, if I remove the PHP tags from the views, I can neither replace the placeholder I use (as was suggested in the links I posted earlier) nor get live content pertaining to a user. But if you feel there’s a workaround this, I’m open to your ideas.

I hope that made at least some sense.

Firstly, I appreciate you taking the advice offered in the end. The fact you did take time to try and learn makes me feel much more motivated to help you now. Thank you! :thumbsup:

The idea of a templating system is to give designers a way to design, without having to learn PHP. And yes, the idea is to abstract the “view” or display logic away from core logic of the application. If you don’t know about MVC architecture, please do read up on it.

The stuff the designers need to learn, the things you feel are not necessary to learn, is what is necessary for them to make their static HTML design become dynamic. If you aren’t building a system where other people are going to be working on the design and who aren’t developers themselves, then you don’t really need a templating system.

I like the fact that you are open to being wrong. Because, you are wrong. :smile: At least from what I am understanding from your post, it sounds like you are wrong. A PHP templating system can never be a “one page” system ala an Angular SPA (if that is what you meant). PHP is a server based language and Angular is a framework built in Javascript that works on the client only. Nothing in PHP works on the client, so the comparison is quite off on that basis alone.

[quote=“nmeri17, post:43, topic:220571”]
Basically, I definitely need attachment of concerns since the variables on these pages are dynamic content being read from the server and are bound to change when a user updates his settings. I think this goes to say I can’t do without server code on that page (which is what I did on this thread before being condemned but let’s not go down that line). [/quote]

Somehow I got lost here. PHP is a server-side language. It is “server code”. If you serve a page (with templates or not) through PHP, it is coming from the server no matter what! :smile:

Very good! I’d say it is a fairly good solution for what it seems you need to get done.

Well, they aren’t storing data in separate files for each request made to the server. I’d say that is a big difference. :smile:

Database calls and classes have no direct relation to each other, so the comparison isn’t quite correct and shouldn’t lead to any deduction that you might need a class now.

All this makes no sense to me, again. Sorry.

Can you try this please? Can you, without using any tech programming jargon, like using PHP or OOP features, explain what should be happening when a user calls a certain page. What data is it you need to have, use, display, store, etc. Explain the whole thing from the user’s perspective first, then try and explain what the server should be doing, but like I said, without any programming jargon. Maybe I can get an understanding of your problem and help you solve it starting from a higher level, instead of at the programming level.

Scott

2 Likes

Hey Molinari. I would be unable to reply fully for now. Yesterday I got hit by a terrible bout of the illness I have and don’t think I’ll do much without an operation. I’ll reply as soon as I can.

Get well soon!!!

Scott

1 Like

Thank you. I am back–at least for now. I’ll reply your posts shortly

I’ll be posting everything this time and try my best to be as simplistic and clear as possible with all concerned code and accompanying comments + explanations.
Now, in my confirm.php script, after confirming new user and updating the database that holds confirmed users, I create a unique page for this new user. This new page picks its format (the way the layout should look a.k.a front end and how data from back end should be arranged) from a prearranged template–which will soon follow-- and initializes it with a primary key. This primary key is what determines the database row we want its info to be displayed on this very page. So, for the relevant line in confirm.php, we have:

include "../classes/member_template_class.php";
$p = new Member_page($row['username'], "member_template_file.php");

$row['username'] is just username. Remember I’m fetching all data from the temporary sign up table into confirm table but that is pointless in the current discussion. Just saying, for clarity sake but think of it as $username: primary key.
We continue.
Then in “…/classes/member_template_class.php”, we have a class that initializes the user’s unique page as its primary function. Secondary function is to supply a helper function to fetch the data pertaining to the page owner. So in “…/classes/member_template_class.php”, I have the following:

class Member_page {
	/*
	* @Author: Al Nmeri
	* @Description: inits new page for user from template supplied
	* ======@constructor=======
	* @param: PAGEOWNER: username of page owner
	* @param: template_file: the file containing member template
	**/
	public function __construct ($PAGEOWNER, $template_file) {
		//fetch template

		$replace_arr = array('/* this loop should check where the array for where the new object matches, fetch that object then store it in the instance static variable */');
		$template_file = str_replace($replace_arr, '', file_get_contents($template_file));

		// init new dir for user
		$pagename = str_replace('_', '.', $PAGEOWNER);
					
		if (mkdir("../$pagename")) {
			file_put_contents("../$pagename/index.php", "<?php define('PAGEOWNER','$PAGEOWNER'); ?>\n");
			
			file_put_contents("../$pagename/index.php", $template_file, FILE_APPEND);
		}
	}

	/*
	* @param: pageOwner: username of current page owner
	* @return: An object with user info as properties
	* SIDE-NOTE: We can't use the Member::fetch_me() because that is dependent on current session name instead * of the PAGEOWNER constant
	**/
	public static function my_data ($pageOwner) {
		$a = $conn->prepare("SELECT * FROM user_info WHERE username=?");
		$a->bindParam(1, $uname);
		$uname = $pageOwner;
		$a->execute();
		return $a->fetch(PDO::FETCH_OBJ);
	}

}

If you’re following, now you know why I have the second parameter in the class I submitted in the confirm.php script so let’s visit the file member_template_file.php.

<?php
session_start();
include "../classes/my_conn.php";
include "../classes/member_template_class.php";

$sess = $_SESSION['username'];

// get connection
$conn = new My_conn($conn_details);
$conn = $conn->gc();

// get user info for page usage
$owner = Member_page::my_data(PAGEOWNER);

	// test whether this is user's first ever login
	if($sess == PAGEOWNER):

	$welcome = $conn->query("SELECT sign_up_date, last_login FROM users WHERE username=PAGEOWNER");
		while ($welcome->fetch(PDO::FETCH_ASSOC)):
			if ($welcome['sign_up_date'] == $welcome['last_login']):
				echo '<p style="background: black; color: #f0f0f0;">Your profile is ready. Click on preferences below to update your info so your friends can find you.</p>';
			endif;
		endwhile;
	endif;
?>

<!DOCTYPE html>
<html lang=en>
<head>
	<meta charset=utf-8>
	
	<link href='../register/member.css' rel='stylesheet' type='text/css'>
	<link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
	<link href='https://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
	<link type="x-image/icon" rel="icon" href="../../favicon.ico">
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>

	<title> <?php echo $owner->name; ?> </title>
</head>

<body>
	<?php include '../header.php'; ?>	
	<main>
	<aside>
	
		<h2> <?php echo $owner->name; ?> </h2>
		<div id=profilePic> <br>
			<img src='<?php echo $owner->profile_pic; ?>' alt="">
		</div>
	
	<div id=bio> <?php echo $owner->bio; ?> </div>
	
	<div id=misc>
		<ul>
		<?php if($sess == PAGEOWNER) {
		?>
			<li> <a href='../a/comments?u=<?php echo PAGEOWNER; ?>'><i class="fa fa-comments"></i> view my comments </a></li>
			<li> <a href='../a/mentions?u=<?php echo PAGEOWNER; ?>'> <span style='font-weight: bold;'>@ </span>my mentions </a> </li>
			<li> <a href='../preferences/'><i class="fa fa-cog"></i> account settings </a> </li>
		<?php
		}
		else {
		?>
			<li> <a href='../a/comments?u=<?php echo PAGEOWNER; ?>'><i class="fa fa-comments"></i> view <?php echo explode(' ', $owner->name)[0] . "'s"?> comments </a></li>
			<li> <a href='../a/published/?author=<?php echo PAGEOWNER; ?>'> <i class="fa fa-file-text"></i> <?php echo explode(' ', $owner->name)[0] . "'s"?> published posts </a> </li>
		<?php
		}
		?>
		</ul>
	</div>
	</aside>
	
		<?php
		if($sess == PAGEOWNER) {
		include $_SERVER['DOCUMENT_ROOT'] . '/register/make_new_post.php';
		}
		?>
	</main>
	
	<?php include '../footer.php'; ?>	
</body>
</html>

So the above script is my template file which as you can see, contains markup expecting dynamic content (and can’t be tied to ‘dumb’/html). Let me recap what the above code I have posted does (or at least is expected to do :sweat_smile: )

  1. When a new user is confirmed, call class Member_page and supply
    a. the primary key
    b. the template file
  2. The Member_page class should take the template file (the view if you like) and initialize it/create it with a primary key–in our case, username. Then append the template as a string to it.
    b. Fill in the placeholders in our view with info from our database (model if you like). This is done using the my_data static method.

So I have my “nifty class” which I mentioned earlier on, which I use to grab information pertaining to a particular user, then display it on that person’s page. I had explaining myself to a six year old in mind, not sure how good that went. But I hope I have not created a bigger disaster by all that long talk and code chunks. If so, just read the last part of the post where I outlined everything in two points.

Hello there. Good thing no one has replied yet. I observed the class I posted in the post directly above this was not robust enough to accommodate needs outside the specific use case of each user’s page. For instance, in the scenario I posted on post #10 of this thread. So I have re-modified the class and also would also rewrite that code in post #10 as a test case of the class. The templating class constructor itself now looks like this

public function __construct ($primary_key, $pagename, $template_file, $pagename_manipulate=NULL) {
		//fetch template

		$replace_arr = array('/* this loop should check where the array for where the new object matches, fetch that object then store it in the instance static variable */');
		$template_file = str_replace($replace_arr, '', file_get_contents($template_file));

		// any page name manipulations go here
		if (!is_null($pagename_manipulate)) {
			$pagename = $pagename_manipulate();
		}

		// init new dir for user
		$pagename = explode('/', $pagename);

		for ($i=0; $i<count($pagename)-1; $i++) { //-1 since we don't need the last part
			if (!is_dir($pagename[$i])) {
				mkdir("../". $pagename[$i]);
			}
		}
		//then repack the page name
		$pagename = implode('/', $pagename);
		file_put_contents("../$pagename/index.php", "<?php define('PAGEOWNER','$primary_key'); ?>\n");
		
		file_put_contents("../$pagename/index.php", $template_file, FILE_APPEND);
	}

So in my confirm.php, I now have


		// create user's unique page
		function manipulate($pagename) {
			return $pagename = str_replace('_', '.', $PAGEOWNER);
		}

		// the second argument can take a function or string as long as the function return a string
		$p = new Member_page($row['username'], $row['username'], "member_template_file.php", manipulate ($row['username']));

So, as a modification to post #10, on that CMS page, I have:

	include "../classes/member_template_class.php";

	$article_title = $_POST['article_title'];
	$article_author = $_POST['article_author'];
	$article_image = $_FILES['banner_image'];
	$article_body = $_POST['article_body'];
	$categories = $_POST['categories'];
	$date = date("l d F, Y");
	
	if (isset($article_title, $article_image, $article_body, $article_author)) {
		function manipulate ($article_title) {
			$temp_link = explode(" ", $article_title);
			$article_link = array();
			for ($i = 0; $i < count($article_title); $i++) {
				if (strlen($temp_link[$i])>3) {
					$article_link[] = $temp_link[$i];
				}
			}
			return $perm_link = $_SERVER['DOCUMENT_ROOT'] . "/" . date('Y/m') . "/" . implode("-", $article_link) . "/";
		}
	// upload banner image
	move_uploaded_file($article_image['tmp_name'], $perm_link . "banner.jpg");

	// update db with posts info
	$blog_post_vars = array($article_title, $article_author, $article_body, $perm_link, $categories, $date);
	$update = $conn->prepare("INSERT INTO blog_posts (article_title, article_author, article_body, article_url, categories, date) VALUES(?, ?, ?, ?, ?, ?)");
	$update->execute($blog_post_vars);

	// then create unique page for post
	$p = new Member_page($article_title, manipulate ($article_title), "../posts/blog_template.php");
	}

And in the “…/posts/blog_template.php”, I call it like I called its variables in my post above:

include "../classes/member_template_class.php";
// grab all post's details
@$post_title = PAGEOWNER; // just using this line for clarification purposes so we know who we dealing with
$curr_post = Member_page::my_data($post_title);
	<main>
		<h2> <?php echo $curr_post->article_title ?> </h2>
		<div id=banner-image> <img src=banner.jpg alt=""> </div>
		<div id=info> by<span id=author> <?php echo $curr_post->article_author; ?> </span> <span id=date> <?php echo $curr_post->date; ?> </span> </div>
//and so on and so forth
</main>

I hope I haven’t missed anything but in case I have or there’s something you don’t understand, just ask. I also hope I don’t give your Xdebug a torrid time :sweat_smile:

This is the reason why people shouldn’t write their own content management systems and frameworks. This is just a complete mess. Its not funny its sad… very sad and inconsiderate to any other developer who will need to maintain this disaster. I’ve been on the end of maintaining stuff like this and it makes me sick considering all the great alternatives with thorough documentation in the ecosystem.

1 Like

I think you and I should have gone past the stage of condemning my code without pointing out what the problem with it is. If I have gone through the pain of sharing my (albeit horrible) code, the least you can do is pinpoint what you feel I’m doing wrong and not resort to such blanket statements. If I were you, and I could clearly see loopholes in @nmeri17’s templating system but I’m too lazy to point it out, I’d at least advice him to add a Big caveat at the top of all his scripts apologizing profusely to the inheriting developer and begging him for forgiveness about the horrors the bugs and code are about to unleash on him. That is at least better than pointing out nothing IMHO.

I have other obligations besides teaching someone intermediate to advanced design patterns for template systems. Besides I don’t write my own template systems… I use the wonderful ones available in the ecosystem and part of the frameworks which I use. For example, in Laravel with blade one would use a view composer to accomplish the same task with much less code and convoluted logic.

There is potential value in “re-inventing the wheel”.

As long as it is for the learning experience, and there are no time constraints.

One thing for sure, “tinkering” will help with understanding other’s work, and give an appreciation of the work done by other Teams of developers.

I’m assuming that nmeri17 's intent at this time is not to write “the next great thing” but to learn.

To that end, looking at some of oddz 's suggested alternatives and studying how they’re put together might help.

4 Likes

I am afraid you are attacking the problem from the wrong angle.

The way the problem you describe is normally solved is by a template engine. Then after the view has been created you can do a granular cache on the content the page consists of, or cache the whole page.

On new visits from the same user (or users if its not unique content tied to a user), instead or creating the page again, the cache is served.

If you want to create your own system doing this, then this is what you need to do.

  1. Create a template class.
  2. Create a cache class.
  3. For each page, take all the code that is now inside the templates, database queries, calling classes etc. and move them into their own page, class etc. The idea is to separate them from the templating code. Then you will pass along all of the required result as values to the templates as they are processed. If any of the parsed templates should be cached, this is also where you do this.
  4. Create barebone html template files (i.e. no database queries, calling classes etc. inside them).

Doing this will separate the concerns of the code, making it easier to maintain and also easier to read.

@nmeri17 - As you can see, you’ve gotten some diverse answers. There is no going into your code, because it is basically so bad, it isn’t worth discussing. That is why I asked if you could explain your programming problem or challenge without using programming (which you unfortunately failed to do. No problem though, you explained enough otherwise to understand your challenge).

Please don’t be disheartened. I too also created total crap in my first projects and that wasn’t all too long ago. :blush:

I’d like to suggest the following, since it seems you are open for learning more. At one point, while you are learning, you’ll go “Holy crap, what was I thinking.” :smile:

So, here are my suggestions.

  • Read up on MVC architecture and especially what it means in the PHP world. Some resources.

This is a really good one!
https://r.je/mvc-in-php.html

  • So, now that you have a fairly good idea of what MVC is, try to rethink your application and how it should work under such an architecture. You should also learn to use a simple/ micro-framework too. Slim or Silex come into mind. Or, if you are really wanting to learn a lot, learn Symfony or Laravel.

    The reason for learning how to use a framework is to get you learning how to program properly in PHP. It helps you, because the frameworks are “leading (you) by (very good) example”. Working with well programmed frameworks starts to give you a feeling of how current best practices are being incorporated into code, so you can also follow suite.

    Using a framework also helps you avoid making really bad mistakes. As you get more and more comfortable with working with a framework (and more importantly, programming in PHP), you can delve into making your own framework or templating engine. But, I think at that point, you’ll realize, you don’t need to reinvent the wheel.

  • As for your current challenge. Once you learn how templating works within MVC, you could easily create base templates for your user’s profile page. I am assuming you don’t want to have a totally different page for each user, do you? I mean, different from a design standpoint. If you don’t, but rather, all you want to do is show different data on the profile page per user, that is exactly what templates, and template engines, are for.

  • Try working with one of the micro-frameworks at first and as a learning challenge, work in the Plates Template System into the framework’s view component. For example http://www.slimframework.com/docs/features/templates.html or you could just go with Twig in Silex: http://silex.sensiolabs.org/doc/master/providers/twig.html

I hope you can take the time to do the learning and take no offense to the “attacks” on your programming. You are clearly a novice programmer and you need to “hit the books” some more. So, do have fun learning! :smile:

Scott

1 Like

Yes my friend! This exactly is what I’m aiming for. Not different content simply served based on the get request-- I mean unique individual pages like site.com/my-personal-page/index.php

Site.com/mr-molinari/index.php

That’s why I need those file writes. Abstracting away logic means I’ll use regular expressions to swap out placeholders every time the page is served and I still need logic to achieve that so it’s more or less the same. I really appreciate your time and effort in curating these links. It’s just a shame I haven’t been able to explain myself properly in neither basic English nor programming syntax. But each user needs a unique page like I have clarified in this post.

What several of us has suggested above, is still the direction you should go. By using a simple MVC with templates, and then caching the view (which can be as simple as creating a file with the content as you do) together with Mod Rewrite (or your web server equivalent) what you want to do becomes very simple.

Then you aren’t building a common CMS. You are building some sort of a multi-tenant system, which requires a whole different approach. How “customizable” would the system be for the users? Is it just the profile page they can customize, or is it the whole application?

Scott

Nope. Just their page. But changes to that their page reflect where they carry out ohter activities on other parts of the site. Like changing the profile picture o my page but it can be visible when I carry out another activity somewhere else on the application.

Then, you might notice I called the class somewhere else; those are for blog posts. They’ll have pages as well. I’m also using the class/system to create pages for sermons too. I think that’s all I can remember for now. In the future, I might still need a “multi-tenant” class of files on the system and you’ll see this system comes in handy. That’s why I need an engine that accepts templates and converts it to a new file that can be live.
On the flip side, I have the categories page which I think I can use the system you all have been suggesting on. To demonstrate its end use case, its URL looks like this: site.com/categories/?cat=romance
In this scenario, I can have a truly abstract view and a controller which would be in form of the index page and would, using regexes, swap out the placeholders like {{tittle}}, {{body}} etc from the view, then serve content from the model based on the value passed in the GET.That’s what I meant when I mentioned a one page application in post # 43 below

When I learnt the Angular js framework on codecademy.com, the use case was a one page application and this was how it worked. I didn’t know the controller is different from what the controller does or if it is part of the Angular framework. I am a staunch framework agnostic so I don’t pay much attention to them anyway. I just looked into it then because the hullabaloo about it has risen to the high heavens. My personal reservations are built around its constrictions–the irony of building something generic for every project conceivable and yet is restricts the developer from having their own freedom to explore or as as @mittineauge mentioned, “tinker”. I’m not an obsessive computer wizard that is crazy about tinkering though, but most of my friends (if not all) use those frameworks and their knowledge of the language these frameworks are built for start and end around that framework. Doesn’t sound like what I want to do with my life.

But at least, progress has been made today; you now know what I am trying to achieve. We can now take the discussion to whether my code accomplishes that and probably pay me bi-quarterly royalties for damages :blush:

I did have this in mind but wasn’t quite sure it would be plausible. It seems sketchy in my head. I don’t feel secure explaining how I would implement that to avoid coming off worse than some people here already regard me. But, my thought process was along the lines of having
site.com/profile/index.php?userid=red.devil666
and then using .htaccess to rewrite every GET request to that page that matches a valid user in the databse into something that looks like a directory which I’m trying to achieve i.e.
site.com/red.devil666/

If that is possible, I still wouldn’t use any of those frameworks anyway. I would simply incorporate a regex engine in my sytem that would swap out the {{title}} and {{body}} in the view which seems to be an eyesore and thorn in the flesh of the esteemed PHP elders of Sitepoint.com. That way, everyone leaves, a winner and the future developer won’t run into problems either.

On a side note, I would like to know: These front end developers we’re trying to protect by abstracting logic, how hard is it for them to simply skip PHP tags or lines that contain it or stuff they can see is not their line of work?