SMF Development > Feature Requests

Moving to something like Handlebars (after 2.1)

(1/13) > >>

Arantor:
So, anyone up for moving to a proper template system after 2.1? Maybe Handlebars. Maybe Twig. Maybe Blade... just something that makes it easier for themers to do their thing without having to master PHP. And making it *tons* easier for people to add in snippets of code without breaking things.

It's a lot of work. I think it'd be worth it.

d3vcho(void):
Sounds interesting 8)

Antes:
I was opposing the idea when it first introduced by Suki. I'm still opposing it. I don't think SMF requires any framework inside it apart from (maybe) source framework. I think for next version maybe SMF can introduce something like loadSnip(), which in theory does the same thing.

I'm not opposing to frameworks in general, what I'm against is using frameworks in SMF. The uniqueness of the software will blow away with usage of frameworks (my opinion not the fact). If we are starting this, why stop there lets use Laravel (or something) Twig (or something), Bootstrap, Font-Awesome and enhance them with 100% jQuery (no native JS).

Arantor:
Awesome, you totally missed the point.

None of what I suggested was a *framework*. I was quite careful to be specific - I didn't say Laravel, I said Blade. I didn't say Symfony, I said Twig. I wasn't proposing using a framework, merely using something so that instead of templates being full of PHP, you could give them to themers without them having to learn PHP.

For example, which is someone more likely to be able to reskin, index.template.php, or:


--- Code: ---<!DOCTYPE html>
<html {{#if context.right_to_left}}dir="rtl" {{/if}}{{#if txt.lang_locale}} lang="{{locale txt.lang_locale}}"{{/if}}>
<head>
<meta charset="UTF-8">
{{#each context.css_files}}
    <link rel="stylesheet" href="{{fileUrl}}">
{{/each}}
   
    {{{javascript deferred=0}}}

<title>{{context.page_title_html_safe}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
{{#each context.meta_tags}}
    <meta {{#if name}}name="{{name}}"{{else}}property="{{property}}"{{/if}}  content="{{content}}">
{{/each}}

<!-- Theme color; feel free to override -->
<meta name="theme-color" content="#557EA0">

{{#if context.robot_no_index}}<meta name="robots" content="noindex">{{/if}}
{{#if context.canonical_url}}<link rel="canonical" href="{{context.canonical_url}}">{{/if}}
<link rel="help" href="{{scripturl}}?action=help">
<link rel="contents" href="{{scripturl}}">
{{#if context.allow_search}}<link rel="search" href="{{scripturl}}?action=search">{{/if}}

<link rel="alternate feed" type="application/rss+xml" title="{{context.forum_name_html_safe}} - {{txt.rss}}" href="{{scripturl}}?action=.xml;type=rss2{{#if context.current_board}};board={{context.current_board}}{{/if}}">
<link rel="alternate feed" type="application/atom+xml" title="{{context.forum_name_html_safe}} - {{txt.atom}}" href="{{scripturl}}?action=.xml;type=atom{{#if context.current_board}};board={{context.current_board}}{{/if}}">

{{#if context.links.next}}<link rel="next" href="{{context.links.next}}">{{/if}}
{{#if context.links.prev}}<link rel="perv" href="{{context.links.prev}}">{{/if}}
{{#if context.current_board}}<link rel="index" href="{{scripturl}}?board={{context.current_board}}.0">{{/if}}
{{{context.html_headers}}}
</head>
{{!--
I apologise for the next line. -Yami
--}}
<body id="{{context.browser_body_id}}" class="action_{{#if context.current_action}}{{context.current_action}}{{else}}{{#if context.current_board}}messageindex{{else}}{{#if context.current_topic}}display{{else}}home{{/if}}{{/if}}{{/if}}{{#if context.current_board}}board_{{context.current_board}}{{/if}}">
    <div id="footerfix">
        <div id="top_section">
        {{#if context.user.is_logged}}
            <ul class="floatleft" id="top_info">
        <li>
        <a href="{{scripturl}}?action=profile" {{#if context.self_profile}} class="active"{{/if}} id="profile_menu_top" onclick="return false;">
        {{#if context.user.avatar}}{{{context.user.avatar.image}}}{{/if}}
        {{context.user.name}}</a>
        <div id="profile_menu" class="top_menu"></div>
        </li>
                <li>
                    <a href="{{scripturl}}?action=profile;area=characters" id="characters_menu_top" onclick="return false;">
                    {{textTemplate txt.posting_as user_info.character_name}} ▼</a>
                    <div id="characters_menu" class="top_menu"></div>
                </li>
       
            {{#if context.allow_pm}}
                <li>
                <a href="{{scripturl}}?action=pm" {{#if context.self_pm}}class="active"{{/if}} id="pm_menu_top">{{txt.pm_short}} {{#if context.user.unread_messages}}<span class="amt"> {{context.user.unread_messages}}{{/if}}</span></a>
                <div id="pm_menu" class="top_menu scrollable"></div>
                </li>
            {{/if}}
           
            <li>
        <a href="{{scripturl}}?action=profile;area=showalerts;u={{context.user.id}}"{{#if context.self_alerts}}class="active"{{/if}} id="alerts_menu_top">{{txt.alerts}}{{#if context.user.alerts}}<span class="amt">{{context.user.alerts}}</span>{{/if}}</a>
        <div id="alerts_menu" class="top_menu scrollable"></div>
        </li>
        </ul>
        {{else}}
            {{#if maintenance}}
            <ul class="floatleft welcome">
        <li>{{login_helper txt.welcome_guest txt.guest_title context.forum_name_html_safe scripturl txt.login}}</li>
        </ul>
        {{else}}
        <ul class="floatleft welcome">
        <li>{{#if context.can_register}}{{login_helper txt.welcome_guest_register txt.guest_title context.forum_name_html_safe scripturl txt.login}}{{else}}{{login_helper txt.welcome_guest txt.guest_title context.forum_name_html_safe scripturl txt.login}}{{/if}}</li>
        </ul>
        {{/if}}
        {{/if}}
       
        {{#if modSettings.userLanguage}}
            {{#if context.languages}}
                <form id="languages_form" method="get" class="floatright">
        <select id="language_select" name="language" onchange="this.form.submit()">
            {{#each context.languages}}
            <option value="{{filename}}"{{isSelected context.user.language filename}}>{{name}}</option>
            {{/each}}
            </select>
        <noscript>
        <input type="submit" value="{{txt.quick_mod_go}}" />
        </noscript>
        </form>
        {{/if}}
        {{/if}}
       
        {{#if context.allow_search}}
        <form id="search_form" class="floatright" action="{{scripturl}}?action=search2" method="post" accept-charset="UTF-8">
        <input type="search" name="search" value="" class="input_text">&nbsp;
                <select name="search_selection">
                    <option value="all">{{txt.search_entireforum}}</option>
                    {{#if context.current_topic}}<option value="topic" selected="selected">{{txt.search_thistopic}}</option>{{/if}}
                    {{#if context.current_board}}<option value="board" selected="selected">{{txt.search_thisbrd}}</option>{{/if}}
                    {{#if context.allow_memberlist}}<option value="members">{{txt.search_members}}</option>{{/if}}
                </select>
                {{#if context.current_topic}}<input type="hidden" name="sd_topic" value="{{context.current_topic}}">{{/if}}
                {{#if context.current_board}}<input type="hidden" name="sd_brd" value="{{context.current_board}}">{{/if}}
                <input type="submit" name="search2" value="{{txt.search}}" class="button_submit">
                <input type="hidden" name="advanced" value="0">
            </form>
        {{/if}}
    </div>
   
    <div id="header">
    <h1 class="forumtitle">
    <a id="top" href="{{scripturl}}">{{#if context.header_logo_url_html_safe}}<img src="{{context.header_logo_url_html_safe}}" alt="{{context.forum_name_html_safe}}">{{else}}{{context.forum_name_html_safe}}{{/if}}</a>
    </h1>
    {{#if settings.site_slogan}}<div id="siteslogan" class="floatright">{{settings.site_slogan}}</div>{{else}}<img id="smflogo" src="{{settings.images_url}}/smflogo.png" alt="Simple Machines Forum" title="Simple Machines Forum">{{/if}}
    </div>
    <div id="wrapper">
    <div id="upper_section">
    <div id="inner_section">
    <div id="inner_wrap">
    <div class="user">
        {{context.current_time}}
    </div>
        <div class="news">
            <h2>{{txt.news}}:</h2>
            <p>{{context.random_news_line}}</p>
            </div>
            <hr class="clear">
    </div>
    <a class="menu_icon mobile_user_menu"></a>
    <div id="mobile_user_menu" class="popup_container">
    <div class="popup_window description">
    <div class="popup_heading">{{txt.mobile_user_menu}}
    <a href="javascript:void(0);" class="generic_icons hide_popup"></a></div>
    {{>menu}}
    </div>
    </div>
    <div id="main_menu">{{>menu}}</div>
    {{#if context.linktree}}
    <div class="navigate_section">
    <ul>
    {{#if context.user.is_logged}}
    <li class="unread_links">
    <a href="{{scripturl}}?action=unread" title="{{txt.unread_since_visit}}">{{txt.view_unread_category}}</a>
    <a href="{{scripturl}}?action=unreadreplies" title="{{txt.show_unread_replies}}">{{txt.unread_replies}}</a>
    </li>
    {{/if}}
    {{#each context.linktree}}
    <li {{#if @last}}class="last"{{/if}}>
        {{#unless @first}}<span class="dividers">{{#if context.right_to_left}}◄{{else}}►{{/if}} </span>{{/unless}}
        {{{extra_before}}}
        {{#if url}}
        <a href="{{url}}"><span>{{{name}}}</span></a>
        {{else}}
            <span>{{{name}}}</span>
        {{/if}}
        {{{extra_after}}}
    </li>
    {{/each}}
    </ul>
    </div>
    {{/if}}
    </div>
        </div>
        <div id="content_section">
    <div id="main_content_section">
                    {{#if (and context.in_maintenance context.user.is_admin)}}
                        <div class="errorbox">
                            <dl>
                                <dt>
                                    <strong id="error_serious">{{txt.forum_in_maintenance}}</strong>
                                </dt>
                                <dd class="error" id="error_list">
                                    {{{textTemplate txt.maintenance_page (concat scripturl '?action=admin;area=serversettings;' context.session_var '=' context.session_id)}}}
                                </dd>
                            </dl>
                        </div>
                    {{/if}}
                    {{>status_messages}}
        {{{content}}}
    </div>
    </div>
    </div>
    </div>
   
    <div id="footer">
    <ul>
    <li class="floatright">
        <a href="{{scripturl}}?action=help">{{txt.help}}</a>
        {{#if modSettings.requireAgreement}}| <a href="{{scripturl}}?action=help;sa=rules">{{txt.terms_and_rules}}</a>{{/if}}
        | <a href="#top_section">{{txt.go_up}} ▲</a>
    </li>
    <li class="copyright">{{{copyright}}}</li>
    </ul>
    {{#if context.show_load_time}}
    <p>{{loadtime}}</p>
    {{/if}}
    </div>

   {{{javascript deferred=1}}}
</body>
</html>

--- End code ---

Because *that* is what I am proposing. Notice how new people now don't have to figure out quoting syntax. Themers don't have to care about template layers or intermashing into PHP. It's just HTML with some nice placeholders to show them where content goes.

Antes:
Excuse me if I made a mistake in there but I think "twig" is a Template Framework ? (no sarcasm). If I have misknowledge please ignore my comment above.

Navigation

[0] Message Index

[#] Next page

Go to full version