3 ms·
At the risk of running afoul of Muphry's Law, your example needs double-quoted strings and curly braces (or your identifiers need to be moved outside the quotes
by frankus 18y ago
At the risk of running afoul of Muphry's Law, your example needs double-quoted strings and curly braces (or your identifiers need to be moved outside the quotes and concatenated in).
At any rate, a downside to this approach is that you can't easily add a class or target (or any other attribute) to the A tag (at least in your simplified example).
Of course you could have an optional named parameter that would allow you to pass them in, e.g.:
function user_profile_link ($user, $attrs) {
return build_tag('a', array_merge(array('href' => "/user/profile/{$user->profile}"), $attrs), $user->name);
}
function build_tag ($tag, $attrs, $content) {
array_walk($attrs, create_function('$value, $name, $list', '{$list[] = htmlentities($name, UTF-8) . "=\"" . htmlentities($value, UTF-8) . "\"";}'), &$list);
return "<$tag " . join(' ', $list) . '>' . (($content !== '') ? htmlentities($content, UTF-8) . "</$tag>" : '/>');
}
But trying to do method-chainey sorts of things in PHP quickly runs into the language's clunky syntax, not to mention keeping track of exactly what level of quotation you're at, and so on. This is one of the reasons I like Ruby, as this kind of stuff is much more natural. Something like this:
def build_tag(tag, attrs, content)
attr_string = attrs.collect { |name, value| h(name) + '="' + h(value) + '"' }.join(' ')
"<#{tag} #{attr_string}>" + ((content != '') ? h(content) + "</#{tag}>" : '/>')
end
Both of these are probably a little denser than a sane person would put into production code, but the Ruby example is much more human-parseable to my eyes. (I'm using rails helper 'h', which could easily be defined in PHP as well).
- ericwaller 18y agoI definitely prefer the ruby build_tag too, php's fine.. until you try to do something even remotely interesting. And yeah, in real code the helpers sometimes need to get a bit more advanced. Something I like to do is add a class name corresponding to the function name (which I usually grab from __FUNCTION__) -- it helps keep a nice consistency between server-side/html/js/css