day 8,

  • Removing a file from all git history
  • Custom Template Engine : overkill or not?
  • Emulating single page web app

Removing file from git history


Forgot to add a file to .gitignore and commited the changes?, well even if you delete it in next commit, anyone can see that file in the commit history.

If the file contains some sensitive information and you pushed the repo to public, it is going to be hard time for you, as removing the file becomes near impossible if anyone has already cloned the repo.

What to do now?, well change all the credentials exposed in the file, remove the file from future commits.

If you still want to remove the file from history you can checkout this gihthub official doc : https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository


Custom Template Engine


In our php assignment, we had to take email from user, send him verification link, send updates, let him un-subscribe. In all this, we had a form with one input field and one button.

Initially, I created different php pages for each of these operations. I was not really happy with this arrangement as the code became so complex for me to manage.

I have worked with django framework before and it has this functionality using which we can embed python variables and few directives inside the html.

I just wanted to come up with something like that, after research (just googling things) I found this huge 1000 slides presentation that was presented by james bannet in pycon , the video is here .

I didn’t watch the whole of it only when he explained how the django internally renders template, and decided to make one for my own project.

<?php
/**
 * Very Simple Template Engine
 *
 */
class TemplateEngine
{
    public function render($template_name, $context = null)
    {
        //find the file
        //get the file as string
        $template = file_get_contents("templates/" . $template_name);

        //if context is null no need to render, just return
        if (!$context) {
            return $template;
        }

        //get the tags that start {{ and end with }}
        $pattern = "/{{\s([^{}\s]+)\s}}/";
        preg_match_all($pattern, $template, $matches, PREG_PATTERN_ORDER);

        //create dictionary of patterns and variables
        $patternsMatched = $matches[0];
        $variableNames = $matches[1];
        $matches = array_combine($patternsMatched, $variableNames);

        // replace tags with data from the context
        foreach ($matches as $pattern => $var) {
            $template = str_replace($pattern, $context[$var], $template);
        }

        //return the template as string
        return $template;
    }
}

?>

This is the whole code, with only function to render the html template.

This is how it works :

  • It takes tow parameters : name of the template and context
  • The context variable should have all the data necessary for the template
  • The regular expression finds all special tags like {{ email }} , then it iterates thorough all of them replacing the tags with their actual value from the context variable.

example usage :

// template file
<form action="{{ action }}"
method="POST"
class="form-center">
<h3> {{ header }} </h3>

<input type="email"
     name="email"
     required id="email" >
     <br>
<input type="submit" value="{{ btn }}" class="btn">
</form>

//php code to render it on webpage 

$context["action"] = "unsubscribe.php";
            $context["header"] = "Unsubscribe to Github Timeline Updates";
            $context["btn"] = "Unsubscribe";
            $unsubscribeForm
               = $templateEngine->render(
                "email-form.html",
                $context
            );
            echo $unsubscribeForm;

Using this introduced many bugs in the code and had to refactor the whole application again.


Emulating single page web app

Why create separate files for each user action when there are very few operations to be performed.

  • Subscribe
  • Unsubscribe

To emulate like this is all happening on the index.php , I used url parameter to convey the index page what to display now.

 /*
    * To emulate single page functionality,
    * forms are rendered conditionally
    * using my custom TemplateEngine
    */
    if (isset($_GET["flow"]) && $_GET["flow"]) {
        $flow = $_GET["flow"];
        switch ($flow) {
        case "enter otp":
            $otpForm = $templateEngine->render("enter-otp.html", "");
            echo $otpForm;
            break;
        case "subscribe":
            $subscribeForm = $templateEngine->render("subscribe-form.html");
            echo $subscribeForm;
            break;

        case "unsubscribe":
            $context["action"] = "unsubscribe.php";
            $context["header"] = "Unsubscribe to Github Timeline Updates";
            $context["btn"] = "Unsubscribe";
            $unsubscribeForm = $templateEngine->render(
                "email-form.html",
                $context
            );
            echo $unsubscribeForm;
            break;

        case "sent verification":
            echo "<p>Please check your email for verification link!</p>";
            break;
        }
    } else {
        echo $templateEngine->render("welcome-form.html");
    }

Why used “” in the first two pages instead of context ?

PHP doesn’t support method overloading like java does, it is not straightforward to mimic method overloading in PHP.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *