Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added functionality to generate hash of values from template #81

Closed
wants to merge 1 commit into from

2 participants

@anyonecancode

Hey - I had a need to do a reverse Mustache - take a template, and generate the hash of expected values. Useful for when a developer needs to quickly and easily know what values a template takes. I added this feature, but this is my first attempt at a pull request, so I'm not sure i'm doing this right - I originally did it in the master branch of my fork, but then realized I should maybe do it in the branch feature/makeHash. Not sure if pull requests are per branch or per repo, so I'm not entirely sure what you'll receive here.

Also, I wasn't sure what kind of unit tests would be appropriate, so that's missing. The example is a viewable example, which is different from what your examples look like - so feel free to take or leave that.

Hope this feature is helpful to others!

@bobthecow
Owner

Sorry to make a moving target for you, but you should check out the 2.0-dev version in the dev branch. The bad news is everything changed. The good news is, it means you can actually use a full parser (rather than regex matching) to generate your hash of values. In your case, you'd do something like...

<?php
$m = new Mustache;
$tree = $m->parse('{{#foo}}{{bar}}{{/foo}}');

The value in $tree is a parse tree of the template, which you can then walk and extract values:

<?php

use Mustache\Mustache;
use Mustache\Tokenizer;

class MustacheHasher {
    public function __construct() {
        $this->mustache = new Mustache;
    }

    public function makeHash($template) {
        $tree = $this->mustache->parse($template);

        return $this->walk($tree);
    }

    private function walk(array $tree) {
        $hash = array();
        foreach ($tree as $node) {
            // extract values
            if (is_array($node)) {
                switch ($node[Tokenizer::TYPE]) {
                    // values
                    case Tokenizer::T_ESCAPED:
                    case Tokenizer::T_UNESCAPED:
                    case Tokenizer::T_UNESCAPED_2:
                        $hash[$node[Tokenizer::NAME]] = '';
                        break;

                    // sections
                    case Tokenizer::T_SECTION:
                    case Tokenizer::T_INVERTED:
                        $hash[$node[Tokenizer::NAME]] = $this->walk($node[Tokenizer::NODES]);
                        break;
                }
            }
        }

        return $hash;
    }
}
@bobthecow
Owner

Closing as this can no longer be merged (and should be way easier in Mustache v2.0).

@bobthecow bobthecow closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 24, 2012
  1. @anyonecancode

    Added functionality to generate hash of values from template

    Philip Schweiger authored anyonecancode committed
This page is out of date. Refresh to see the latest.
View
55 Mustache.php
@@ -857,6 +857,61 @@ protected function _varIsIterable($var) {
protected function _varIsCallable($var) {
return !is_string($var) && is_callable($var);
}
+
+ /**
+ * Generate a hash of expected values from a given template
+ *
+ * @access public
+ * @param string $template (default: null)
+ * @return array hash of expected variables
+ */
+ public function generateHash($template = null) {
+ $template = ($template)?
+ $template :
+ $this->_template;
+
+ //Extract all variables from the template
+ preg_match_all('/{{([^}]+)/',$template,$matches);
+ $tags = $matches[1];
+
+ //Turn the resulting flat array into a multidimensional one
+ $i = 0;
+ return $this->_tagsToHash($tags, $i);
+ }
+
+ /**
+ * Private helper function for generateHash
+ * Turns flat array of tags into multidimensional array
+ *
+ * @author Philip Schweiger <pschwei1@gmail.com>, with assistance on
+ * recursion logic from khael on SO (http://stackoverflow.com/users/926474/)
+ * @access private
+ * @param array $tags flat array of tags
+ * @param int &$i current index value as function loops through $tags
+ * @param string $current_tag
+ */
+ private function _tagsToHash($tags, &$i, $current_tag = '') {
+ $nested = array();
+ $tot = count($tags);
+ while ($i < $tot):
+ $tag = $tags[$i];
+
+ if ($tag[0] === '/') {
+ $i++;
+ return $nested;
+ } elseif ($tag[0] === '#') {
+ $tag = str_replace('#','',$tag);
+ $i++;
+ $nested[$tag] = $this->_tagsToHash($tags, $i, $tag);
+ } else {
+ $nested[$tag] = '';
+ $i++;
+ }
+ endwhile;
+ return $nested;
+ }
+
+
}
View
59 examples/makehash/index.php
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+ <meta charset="UTF-8">
+ <title>Mustache Example: make hash</title>
+</head>
+<body>
+ <h1>Mustache Example: make hash</h1>
+
+ <p>Most Mustache examples take a hash and use it to populate the variables in a template. This one goes the other way &ndash; assuming you have a template with mustache variables, it will generate an empty hash.</p>
+
+ <p>This is useful for cases where the person writing the template and the person who will be using it are not the same person, and you need a quick and easy way to let the person populating the template know what variables are expected.</p>
+
+ <h2>The Template</h2>
+
+ <p>Here is our template:</p>
+
+ <pre>
+ &lt;h1>{{header}}&lt;/h1>
+{{#bug}}
+{{/bug}}
+
+{{#items}}
+ {{#first}}
+ &lt;li>&lt;strong>{{name}}&lt;/strong>&lt;/li>
+ {{/first}}
+ {{#link}}
+ &lt;li>&lt;a href="{{url}}">{{name}}&lt;/a>&lt;/li>
+ {{/link}}
+{{/items}}
+
+{{#empty}}
+ &lt;p>The list is empty.&lt;/p>
+{{/empty}}
+ </pre>
+
+ <h2>The Code</h2>
+
+ <p>Run the template through Mustache <br />
+ (assume that we have assigned the above template to the variable $template):</p>
+
+ <pre>
+ $m = new Mustache($template);
+ //Returns an associative array - format as json for output purposes
+ echo json_encode($m->generateHash());
+ </pre>
+
+ <h2>The Result</h2>
+
+ <pre>
+<?php
+require_once '../../Mustache.php';
+$template = file_get_contents('template.txt');
+$m = new Mustache($template);
+echo json_encode($m->generateHash());
+?>
+ </pre>
+</body>
+</html>
View
16 examples/makehash/template.txt
@@ -0,0 +1,16 @@
+<h1>{{header}}</h1>
+{{#bug}}
+{{/bug}}
+
+{{#items}}
+ {{#first}}
+ <li><strong>{{name}}</strong></li>
+ {{/first}}
+ {{#link}}
+ <li><a href="{{url}}">{{name}}</a></li>
+ {{/link}}
+{{/items}}
+
+{{#empty}}
+ <p>The list is empty.</p>
+{{/empty}}
Something went wrong with that request. Please try again.