]> git.andy128k.dev Git - ipf.git/commitdiff
migrate admin to Twig
authorAndrey Kutejko <andy128k@gmail.com>
Fri, 15 Mar 2019 00:58:34 +0000 (01:58 +0100)
committerAndrey Kutejko <andy128k@gmail.com>
Fri, 15 Mar 2019 08:22:17 +0000 (09:22 +0100)
28 files changed:
composer.json
composer.lock
ipf/admin/app.php
ipf/admin/component.php
ipf/admin/controllers/base.php
ipf/admin/controllers/dashboard.php
ipf/admin/controllers/file_browser.php
ipf/admin/controllers/user.php
ipf/admin/templates/admin/base.html [deleted file]
ipf/admin/templates/admin/base.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/change.html [deleted file]
ipf/admin/templates/admin/change.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/delete.html [deleted file]
ipf/admin/templates/admin/delete.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/filebrowser.html [deleted file]
ipf/admin/templates/admin/filebrowser.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/index.html [deleted file]
ipf/admin/templates/admin/index.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/items.html [deleted file]
ipf/admin/templates/admin/items.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/log.html [deleted file]
ipf/admin/templates/admin/log.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/login.html [deleted file]
ipf/admin/templates/admin/login.html.twig [new file with mode: 0644]
ipf/admin/templates/admin/logout.html [deleted file]
ipf/admin/templates/admin/logout.html.twig [new file with mode: 0644]
ipf/project_template.php
ipf/twig.php [new file with mode: 0644]

index 01a35ace3ee035224bf94135835706ab1529bf40..301c27e7fce3da6df980314504e7ba3324e294c9 100644 (file)
@@ -23,8 +23,8 @@
     "andy128k/migrations": "dev-master",
     "andy128k/pegp": "0.1.*@dev",
     "andy128k/routeexpression": "dev-master",
-    "andy128k/ipf-legacy-template": "dev-master",
-    "pimple/pimple": "~3.0"
+    "pimple/pimple": "~3.0",
+    "twig/twig": "~1"
   },
   "require-dev": {
     "phpunit/phpunit": "5"
index 6c907b7ba09898c85214da69ddefde2c007bac76..eef01520ca757fdb8772df4563e21728d66476c2 100644 (file)
@@ -4,69 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "6efa15ba9b218a571e0da69898cfc2d1",
+    "content-hash": "f67dddca5aa2e90df76556d1f8daa79b",
     "packages": [
-        {
-            "name": "andy128k/ipf-legacy-template",
-            "version": "dev-master",
-            "source": {
-                "type": "git",
-                "url": "git://git.andy128k.net/ipf-legacy-template.git",
-                "reference": "3a3db428fb525f3612feda7ee1bc4bdf3aef412a"
-            },
-            "require": {
-                "andy128k/ipf-template": "0.2.*@dev"
-            },
-            "suggest": {
-                "andy128k/ipf": "Web Framework"
-            },
-            "type": "library",
-            "autoload": {
-                "classmap": [
-                    "src"
-                ]
-            },
-            "authors": [
-                {
-                    "name": "Andrey Kutejko",
-                    "email": "andy128k@gmail.com"
-                }
-            ],
-            "time": "2016-02-28T17:52:16+00:00"
-        },
-        {
-            "name": "andy128k/ipf-template",
-            "version": "0.2.x-dev",
-            "source": {
-                "type": "git",
-                "url": "git://git.andy128k.net/ipf-template.git",
-                "reference": "44dff45da6bd050ee59802d17460c2344ada9d11"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "4.4.*"
-            },
-            "type": "library",
-            "autoload": {
-                "classmap": [
-                    "lib"
-                ]
-            },
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Alex Litovchenko",
-                    "email": "alex.litovchenko@gmail.com"
-                },
-                {
-                    "name": "Andrey Kutejko",
-                    "email": "andy128k@gmail.com"
-                }
-            ],
-            "description": "Template Engine extracted from IPF Web Framework",
-            "time": "2016-02-28T14:48:53+00:00"
-        },
         {
             "name": "andy128k/migrations",
             "version": "dev-master",
         },
         {
             "name": "pear/pear-core-minimal",
-            "version": "v1.10.7",
+            "version": "v1.10.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/pear/pear-core-minimal.git",
-                "reference": "19a3e0fcd50492c4357372f623f55f1b144346da"
+                "reference": "742be8dd68c746a01e4b0a422258e9c9cae1c37f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/19a3e0fcd50492c4357372f623f55f1b144346da",
-                "reference": "19a3e0fcd50492c4357372f623f55f1b144346da",
+                "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/742be8dd68c746a01e4b0a422258e9c9cae1c37f",
+                "reference": "742be8dd68c746a01e4b0a422258e9c9cae1c37f",
                 "shasum": ""
             },
             "require": {
                 }
             ],
             "description": "Minimal set of PEAR core files to be used as composer dependency",
-            "time": "2018-12-05T20:03:52+00:00"
+            "time": "2019-03-13T18:15:44+00:00"
         },
         {
             "name": "pear/pear_exception",
                 "psr"
             ],
             "time": "2018-12-29T15:36:03+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "82ebae02209c21113908c229e9883c419720738a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
+                "reference": "82ebae02209c21113908c229e9883c419720738a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.11-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                },
+                {
+                    "name": "Gert de Pagter",
+                    "email": "backendtea@gmail.com"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "time": "2019-02-06T07:57:58+00:00"
+        },
+        {
+            "name": "twig/twig",
+            "version": "1.x-dev",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/twigphp/Twig.git",
+                "reference": "a482da9fd0a0c00f7d8d6eb810538f9a02f1d08a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/a482da9fd0a0c00f7d8d6eb810538f9a02f1d08a",
+                "reference": "a482da9fd0a0c00f7d8d6eb810538f9a02f1d08a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0",
+                "symfony/polyfill-ctype": "^1.8"
+            },
+            "require-dev": {
+                "psr/container": "^1.0",
+                "symfony/debug": "^2.7",
+                "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.38-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Twig_": "lib/"
+                },
+                "psr-4": {
+                    "Twig\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com",
+                    "homepage": "http://fabien.potencier.org",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Armin Ronacher",
+                    "email": "armin.ronacher@active-4.com",
+                    "role": "Project Founder"
+                },
+                {
+                    "name": "Twig Team",
+                    "homepage": "https://twig.symfony.com/contributors",
+                    "role": "Contributors"
+                }
+            ],
+            "description": "Twig, the flexible, fast, and secure template language for PHP",
+            "homepage": "https://twig.symfony.com",
+            "keywords": [
+                "templating"
+            ],
+            "time": "2019-03-14T13:57:20+00:00"
         }
     ],
     "packages-dev": [
             "homepage": "https://github.com/sebastianbergmann/version",
             "time": "2015-06-21T13:59:46+00:00"
         },
-        {
-            "name": "symfony/polyfill-ctype",
-            "version": "dev-master",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "82ebae02209c21113908c229e9883c419720738a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
-                "reference": "82ebae02209c21113908c229e9883c419720738a",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "suggest": {
-                "ext-ctype": "For best performance"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.11-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Ctype\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                },
-                {
-                    "name": "Gert de Pagter",
-                    "email": "backendtea@gmail.com"
-                }
-            ],
-            "description": "Symfony polyfill for ctype functions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "ctype",
-                "polyfill",
-                "portable"
-            ],
-            "time": "2019-02-06T07:57:58+00:00"
-        },
         {
             "name": "symfony/yaml",
             "version": "3.4.x-dev",
         "andy128k/missing-tools": 20,
         "andy128k/migrations": 20,
         "andy128k/pegp": 20,
-        "andy128k/routeexpression": 20,
-        "andy128k/ipf-legacy-template": 20
+        "andy128k/routeexpression": 20
     },
     "prefer-stable": false,
     "prefer-lowest": false,
index ab04895faf0058839f5725d3f6d461deccaf2fcf..50ac73bedb7b6f737fa837b036a2895eafd77e70 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 
 use Doctrine\DBAL\Connection;
-use PFF\Functions as F;
 use Pimple\Container;
 
 class IPF_Admin_App extends IPF_Application
@@ -84,7 +83,7 @@ class IPF_Admin_App extends IPF_Application
         return array(
             'IPF_VER' => IPF::version(),
             'admin_title' => IPF::get('admin_title'),
-            'app_list' => F::bind(array($this, 'appList'), $request),
+            'app_list' => $this->appList($request),
         );
     }
 
index 272ee7452ba094353b5882b6867338e6c6f93e47..73677a409b981ad32cbb4574b9f32e5557be6902 100644 (file)
@@ -127,22 +127,22 @@ abstract class IPF_Admin_Component
 
     public function listTemplate()
     {
-        return 'admin/items.html';
+        return 'admin/items.html.twig';
     }
 
     public function addTemplate()
     {
-        return 'admin/change.html';
+        return 'admin/change.html.twig';
     }
 
     public function editTemplate()
     {
-        return 'admin/change.html';
+        return 'admin/change.html.twig';
     }
 
     public function deleteTemplate()
     {
-        return 'admin/delete.html';
+        return 'admin/delete.html.twig';
     }
 
     protected function extraMedia($form)
index 796109b7b9521dd3e72684082e5752ca9d5a55e4..77efb17246f01d55d6fc6155197145e675555bc6 100644 (file)
@@ -13,7 +13,7 @@ abstract class IPF_Admin_Base_Controller extends IPF_Controller
 
     protected function render($template, $params)
     {
-        return IPF_Shortcuts::RenderToResponse($template, $params, $this->request);
+        return new IPF_HTTP_Response(IPF_Twig::render($template, $params, $this->request));
     }
 
     /**
index 35d514bc131f3a88e189a3afb5a2f5a36ccc7028..89462f27a4ca21c92724e5c1cdb15bbecd1ea697 100644 (file)
@@ -18,7 +18,7 @@ class IPF_Admin_Dashboard_Controller extends IPF_Admin_Base_Controller
             'page_title' => __('Site Administration'),
             'admin_log' => $this->adminLog()->recent(),
         );
-        return $this->render('admin/index.html', $context);
+        return $this->render('admin/index.html.twig', $context);
     }
 
     function log()
@@ -40,6 +40,6 @@ class IPF_Admin_Dashboard_Controller extends IPF_Admin_Base_Controller
             'current_page' => $currentPage,
             'pages' => $pages,
         );
-        return $this->render('admin/log.html', $context);
+        return $this->render('admin/log.html.twig', $context);
     }
 }
index 5fad612988cedd28c34fb5e80d4212e98c2b5602..342509db226f02197dbb0e6ab5a91d579014a93b 100644 (file)
@@ -131,7 +131,7 @@ class IPF_Admin_FileBrowser_Controller extends IPF_Admin_Base_Controller
             'curr_dir' => $this->relative,
             'parent_dir' => $parent_dir,
         );
-        return $this->render('admin/filebrowser.html', $context);
+        return $this->render('admin/filebrowser.html.twig', $context);
     }
 
     protected function backToIndex()
index 8a5613922ce20dd4f8b47d76f86f992f99378ced..4f3e8f919ea741f814f52ddd500739e61e040e80 100644 (file)
@@ -36,7 +36,7 @@ class IPF_Admin_User_Controller extends IPF_Admin_Base_Controller
             'page_title' => IPF::get('admin_title'),
             'form' => $form,
         );
-        return $this->render('admin/login.html', $context);
+        return $this->render('admin/login.html.twig', $context);
     }
 
     function logout()
@@ -45,7 +45,7 @@ class IPF_Admin_User_Controller extends IPF_Admin_Base_Controller
         $context = array(
             'page_title' => IPF::get('admin_title'),
         );
-        return $this->render('admin/logout.html', $context);
+        return $this->render('admin/logout.html.twig', $context);
     }
 
     function impersonate()
diff --git a/ipf/admin/templates/admin/base.html b/ipf/admin/templates/admin/base.html
deleted file mode 100644 (file)
index d4dee94..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  {block css}
-  <link rel="stylesheet" type="text/css" href="{$STATIC_URL}admin/admin.css">
-  <link rel="stylesheet" type="text/css" href="{$STATIC_URL}admin/admin-print.css" media="print">
-  {/block}
-  <title>{$page_title}</title>
-</head>
-
-<body>
-
-<div id="container">
-  <div class="header">
-    {block sidebar_toggle}
-    <input id="toggle-sidebar" class="toggle-sidebar" type="checkbox">
-    <label for="toggle-sidebar" title="{trans 'Open sidebar'}">&#9776;</label>
-    {/block}
-
-    <div id="branding">
-      <h1 id="site-name"><a href="{$indexpage_url}">{$admin_title}</a></h1>
-    </div>
-    {block usertools}
-      <div id="user-tools">
-        {trans 'Welcome'}, <strong>{$user}</strong>. <a href="{url array('IPF_Admin_User_Controller', 'logout')}">{trans 'Log out'}</a><br />
-        <span id="ipfver">Version: {$IPF_VER}</span>
-      </div>
-    {/block}
-  </div>
-  {block navigation}
-    <div class="navigation">
-      {block breadcrumbs}{/block}
-
-      {block sidebar}
-      <div class="sidebar">
-        <div class="header"></div>
-
-        <ul>
-          <li>
-            <h3><a href="{url array('IPF_Admin_Dashboard_Controller', 'index')}">{trans 'Home'}</a></h3>
-          </li>
-          {foreach $app_list() as $app}
-          <li>
-            <h3>{$app.name}</h3>
-            <ul>
-              {foreach $app.components as $component}
-              <li><a href="{url array('IPF_Admin_Components_Controller', 'listItems'), array($app.path, $component->slug)}">{$component->name}</a></li>
-              {/foreach}
-            </ul>
-          </li>
-          {/foreach}
-          <li>
-            <h3><a href="{url array('IPF_Admin_Dashboard_Controller', 'log')}">{trans 'Recent Actions'}</a></h3>
-          </li>
-        </ul>
-      </div>
-      {/block}
-
-    </div>
-  {/block}
-  {block content}{/block}
-  <div id="footer"></div>
-</div>
-
-{block commonjs}
-  <script src="{$STATIC_URL}admin/admin.js"></script>
-{/block}
-{block scripts}{/block}
-</body>
-</html>
-
diff --git a/ipf/admin/templates/admin/base.html.twig b/ipf/admin/templates/admin/base.html.twig
new file mode 100644 (file)
index 0000000..ce523eb
--- /dev/null
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  {% block css %}
+  <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/admin.css">
+  <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/admin-print.css" media="print">
+  {%  endblock %}
+  <title>{{ page_title }}</title>
+</head>
+
+<body>
+
+<div id="container">
+  <div class="header">
+    {% block sidebar_toggle %}
+    <input id="toggle-sidebar" class="toggle-sidebar" type="checkbox">
+    <label for="toggle-sidebar" title="{{ trans('Open sidebar') }}">&#9776;</label>
+    {% endblock %}
+
+    <div id="branding">
+      <h1 id="site-name"><a href="{{ indexpage_url }}">{{ admin_title }}</a></h1>
+    </div>
+    {% block usertools %}
+      <div id="user-tools">
+        {{ trans('Welcome') }}, <strong>{{ user }}</strong>. <a href="{{ url(['IPF_Admin_User_Controller', 'logout']) }}">{{ trans('Log out') }}</a><br />
+        <span id="ipfver">Version: {{ IPF_VER }}</span>
+      </div>
+    {% endblock %}
+  </div>
+  {% block navigation %}
+    <div class="navigation">
+      {% block breadcrumbs %}{% endblock %}
+
+      {% block sidebar %}
+      <div class="sidebar">
+        <div class="header"></div>
+
+        <ul>
+          <li>
+            <h3><a href="{{ url(['IPF_Admin_Dashboard_Controller', 'index']) }}">{{ trans('Home') }}</a></h3>
+          </li>
+          {% for app in app_list %}
+          <li>
+            <h3>{{ app.name }}</h3>
+            <ul>
+              {% for component in app.components %}
+              <li><a href="{{ url(['IPF_Admin_Components_Controller', 'listItems'], [app.path, component.slug]) }}">{{ component.name }}</a></li>
+              {% endfor %}
+            </ul>
+          </li>
+          {% endfor %}
+          <li>
+            <h3><a href="{{ url(['IPF_Admin_Dashboard_Controller', 'log']) }}">{{ trans('Recent Actions') }}</a></h3>
+          </li>
+        </ul>
+      </div>
+      {% endblock %}
+
+    </div>
+  {% endblock %}
+  {% block content %}{% endblock %}
+  <div id="footer"></div>
+</div>
+
+{% block commonjs %}
+  <script src="{{ STATIC_URL }}admin/admin.js"></script>
+{% endblock %}
+{% block scripts %}{% endblock %}
+</body>
+</html>
diff --git a/ipf/admin/templates/admin/change.html b/ipf/admin/templates/admin/change.html
deleted file mode 100644 (file)
index 2126e49..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-{extends "admin/base.html"}
-
-{block css}
-{superblock}
-{foreach $extra_css as $css}
-{$css|safe}
-{/foreach}
-{/block}
-
-{block breadcrumbs}
-<div class="breadcrumbs">
-  <a href="{url array('IPF_Admin_Dashboard_Controller', 'index')}">{trans 'Home'}</a> &raquo;
-  <a href="{url array('IPF_Admin_Components_Controller', 'listItems'), array($app->slug(), $component->slug())}">{$classname}</a> &raquo;
-  {$page_title}
-</div>
-{/block}
-
-{block content}
-<div id="content" class="colM">
-    <h1>{$page_title}</h1>
-    <div id="content-main">
-        <ul class="object-tools">
-          {block objecttools}
-            {foreach $objecttools as $ot_index => $ot_action}
-              <li>
-              {if $ot_action['method'] == 'POST'}
-                <form id="id_ot_{$ot_index}" method="post" action="{$ot_action['url']}"><a href="javascript:void()" onclick="document.getElementById('id_ot_{$ot_index}').submit();">{$ot_action['title']}</a></form>
-              {else}
-                <a href="{$ot_action['url']}">{$ot_action['title']}</a>
-              {/if}
-              </li>
-            {/foreach}
-          {/block}
-        </ul>
-        <form method="post" enctype="multipart/form-data">
-        <input type="hidden" name="ipf_referrer" value="{$ipf_referrer}">
-        <div>
-            {if $errors}
-            <p class="errornote">Please correct the error below.</p>
-            {/if}
-            <fieldset class="module aligned">
-              {block form}
-                {$form_html|safe}
-              {/block}
-            </fieldset>
-            <div class="submit-row change-form">
-                {if ($mode=='change') && $can_delete}<p class="float-left"><a href="{url array('IPF_Admin_Components_Controller', 'deleteItem'), array($app->slug(), $component->slug(), $object_id)}?ipf_referrer={$ipf_referrer}" class="deletelink">{trans 'Delete'}</a></p>{/if}
-                {if ($mode=='change') && $can_change}<input type="submit" value="{trans 'Save'}" class="default" />{/if}
-                {if ($mode=='add') && $can_add}<input type="submit" value="{trans 'Add'}" class="default" />{/if}
-                <input type="button" value="{trans 'Cancel'}" onclick="javascript:history.back();" />
-            </div>
-        </div>
-        </form>
-    </div>
-    <br class="clear" />
-</div>
-{/block}
-
-{block scripts}
-{foreach $extra_js as $js}
-{$js|safe}
-{/foreach}
-{/block}
-
diff --git a/ipf/admin/templates/admin/change.html.twig b/ipf/admin/templates/admin/change.html.twig
new file mode 100644 (file)
index 0000000..a8ddc2e
--- /dev/null
@@ -0,0 +1,63 @@
+{% extends "admin/base.html.twig" %}
+
+{% block css %}
+{{ parent() }}
+{% for css in extra_css %}
+{{ css|raw }}
+{% endfor %}
+{% endblock %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+  <a href="{{ url(['IPF_Admin_Dashboard_Controller', 'index']) }}">{{ trans('Home') }}</a> &raquo;
+  <a href="{{ url(['IPF_Admin_Components_Controller', 'listItems'], [app.slug, component.slug]) }}">{{ classname }}</a> &raquo;
+  {{ page_title }}
+</div>
+{% endblock %}
+
+{% block content %}
+<div id="content" class="colM">
+    <h1>{{ page_title }}</h1>
+    <div id="content-main">
+        <ul class="object-tools">
+          {% block objecttools %}
+            {% for ot_index, ot_action in objecttools %}
+              <li>
+              {% if ot_action.method == 'POST' %}
+                <form id="id_ot_{{ ot_index }}" method="post" action="{{ ot_action.url }}"><a href="javascript:void()" onclick="document.getElementById('id_ot_{{ ot_index }}').submit();">{{ ot_action.title }}</a></form>
+              {% else %}
+                <a href="{{ ot_action.url }}">{{ ot_action.title }}</a>
+              {% endif %}
+              </li>
+            {% endfor %}
+          {% endblock %}
+        </ul>
+        <form method="post" enctype="multipart/form-data">
+        <input type="hidden" name="ipf_referrer" value="{{ ipf_referrer }}">
+        <div>
+            {% if errors %}
+            <p class="errornote">Please correct the error below.</p>
+            {% endif %}
+            <fieldset class="module aligned">
+              {% block form %}
+                {{ form_html|raw }}
+              {% endblock %}
+            </fieldset>
+            <div class="submit-row change-form">
+                {% if mode == 'change' and can_delete %}<p class="float-left"><a href="{{ url(['IPF_Admin_Components_Controller', 'deleteItem'], [app.slug, component.slug, object_id]) }}?ipf_referrer={{ ipf_referrer }}" class="deletelink">{{ trans('Delete') }}</a></p>{% endif %}
+                {% if mode == 'change' and can_change %}<input type="submit" value="{{ trans('Save') }}" class="default" />{% endif %}
+                {% if mode == 'add' and can_add %}<input type="submit" value="{{ trans('Add') }}" class="default" />{% endif %}
+                <input type="button" value="{{ trans('Cancel') }}" onclick="javascript:history.back();" />
+            </div>
+        </div>
+        </form>
+    </div>
+    <br class="clear" />
+</div>
+{% endblock %}
+
+{% block scripts %}
+{% for js in extra_js %}
+{{ js|raw }}
+{% endfor %}
+{% endblock %}
diff --git a/ipf/admin/templates/admin/delete.html b/ipf/admin/templates/admin/delete.html
deleted file mode 100644 (file)
index d73ae97..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-{extends "admin/base.html"}
-
-{block breadcrumbs}
-<div class="breadcrumbs">
-  <a href="{url array('IPF_Admin_Dashboard_Controller', 'index')}">{trans 'Home'}</a> &raquo;
-  <a href="{url array('IPF_Admin_Components_Controller', 'listItems'), array($app->slug(), $component->slug())}">{$classname}</a> &raquo;
-  <a href="{url array('IPF_Admin_Components_Controller', 'editItem'), array($app->slug(), $component->slug(), $object_id)}">{$object}</a> &raquo;
-  {$page_title}
-</div>
-{/block}
-
-{block content}
-<div id="content" class="colM">
-  <h1>{$page_title}</h1>
-  <form method="post">
-    <input type="hidden" name="ipf_referrer" value="{$ipf_referrer}">
-    <p>Are you sure you want to delete <em>{$object}</em>?</p>
-    <input type="submit" value="Yes, delete it!" class="default" />
-    <input type="button" value="Cancel" onclick="javascript:history.back();" />
-  </form>    
-</div>
-{/block}
-
diff --git a/ipf/admin/templates/admin/delete.html.twig b/ipf/admin/templates/admin/delete.html.twig
new file mode 100644 (file)
index 0000000..3181caf
--- /dev/null
@@ -0,0 +1,22 @@
+{% extends "admin/base.html.twig" %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+  <a href="{{ url(['IPF_Admin_Dashboard_Controller', 'index']) }}">{{ trans('Home') }}</a> &raquo;
+  <a href="{{ url(['IPF_Admin_Components_Controller', 'listItems'], [app.slug, component.slug]) }}">{{ classname }}</a> &raquo;
+  <a href="{{ url(['IPF_Admin_Components_Controller', 'editItem'], [app.slug, component.slug, object_id]) }}">{{ object }}</a> &raquo;
+  {{ page_title }}
+</div>
+{% endblock %}
+
+{% block content %}
+<div id="content" class="colM">
+  <h1>{{ page_title }}</h1>
+  <form method="post">
+    <input type="hidden" name="ipf_referrer" value="{{ ipf_referrer }}">
+    <p>Are you sure you want to delete <em>{{ object }}</em>?</p>
+    <input type="submit" value="Yes, delete it!" class="default" />
+    <input type="button" value="Cancel" onclick="javascript:history.back();" />
+  </form>    
+</div>
+{% endblock %}
diff --git a/ipf/admin/templates/admin/filebrowser.html b/ipf/admin/templates/admin/filebrowser.html
deleted file mode 100644 (file)
index a50f5c0..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-
-  <link rel="stylesheet" type="text/css" href="{$STATIC_URL}admin/admin.css">
-  <link rel="stylesheet" type="text/css" href="{$STATIC_URL}admin/admin-print.css" media="print">
-  <style>
-  {literal}
-    html, body {height: 100%;padding:0; margin:0; overflow: hidden;}
-
-    .columns {height: 100%;width:100%;padding:0; margin:0;}
-
-    .sidebar-column {width:250px; height: 100%; border-right:1px dashed #a0a0a0; padding: 0 10px;float: left}
-
-    .hr { border-top:1px dashed #a0a0a0; margin-top:5px; padding-top:5px; }
-
-    .content-column {padding: 0 10px;margin-left:270px;height:100%;}
-    .breadcrumbs {padding:10px 0;height:20px;line-height:20px}
-    .content-column .module {width:100%; height: calc(100% - 90px); overflow:auto; margin: 0;}
-
-    .submit-row {height: 30px;padding: 10px 0; text-align: right;}
-
-    #pic { border:2px solid white; width:240px; text-align:center; height: 150px; line-height: 150px; background: #888; }
-    #pic img { max-width: 240px; max-height: 150px; display:none; }
-
-    #prop { display:none; position:absolute; left:0; top:0; z-index:400000; border:2px solid #aaa; background: #888; }
-    #prop img {max-width:100px;max-height:100px}
-
-    .file-selected {display: none}
-  {/literal}
-  </style>
-
-  <title>{$page_title} - IPF Administration</title>
-</head>
-<body>
-  {assign $zero_gif = "data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="}
-
-  <div class="columns">
-    <div class="sidebar-column">
-      <!-- sidebar -->
-      <form method="post" action="{url array('IPF_Admin_FileBrowser_Controller', 'mkdir')}">
-        <h3>Add Folder</h3>
-        <input type="hidden" name="dir" value="{$curr_dir}">
-        <input name="name">
-        <input type="submit" value="Create">
-      </form>
-
-      <div class="hr"></div>
-
-      <form method="post" enctype="multipart/form-data" action="{url array('IPF_Admin_FileBrowser_Controller', 'upload')}">
-        <h3>Upload File</h3>
-        <input type="file" name="files[]" multiple="multiple">
-        <input type="hidden" name="dir" value="{$curr_dir}">
-        <input type="submit" value="Upload">
-      </form>
-
-      <div class="file-selected">
-        <div class="hr"></div>
-
-        <h3>File Option</h3>
-        <form method="post" action="{url array('IPF_Admin_FileBrowser_Controller', 'rename')}">
-          <input type="hidden" name="old_name" id="id_old_name">
-          <input type="hidden" name="dir" value="{$curr_dir}">
-          <input name="new_name" id="id_new_name">
-          <input type="submit" value="Rename">
-        </form>
-
-        <br>
-
-        <form method="post" action="{url array('IPF_Admin_FileBrowser_Controller', 'move')}">
-          <input type="hidden" name="name" id="id_old_name2">
-          <input type="hidden" name="dir" value="{$curr_dir}">
-          <select name="destination">{foreach $dirtree as $dir}<option value="{$dir['path']}">{$dir['name']}</option>{/foreach}</select>
-          <input type="submit" value="Move To">
-        </form>
-
-        <div class="hr"></div>
-
-        <h3>View File</h3>
-        <div id="pic"><img src="{$zero_gif}"></div>
-      </div>
-      <!-- /sidebar -->
-    </div>
-
-    <div class="content-column">
-      <!-- content -->
-
-        <div class="breadcrumbs">
-          <a href="{url array('IPF_Admin_FileBrowser_Controller', 'index')}?dir=">Root</a>
-          {foreach $path as $p}
-            / <a href="{url array('IPF_Admin_FileBrowser_Controller', 'index')}?dir={$p['dir']}">{$p['name']}</a>
-          {/foreach}
-        </div>
-
-        <div class="module" id="changelist">
-          <table>
-            <thead>
-              <tr>
-                <th>Name</th>
-                <th>Type</th>
-                <th>Size</th>
-                <th>Delete</th>
-              </tr>
-            </thead>
-            <tbody>
-            {if $curr_dir}
-              <tr>
-                <td><a href="{url array('IPF_Admin_FileBrowser_Controller', 'index')}?dir={$parent_dir}">..</a></td>
-                <td>UP-DIR</td>
-                <td></td>
-                <td></td>
-              </tr>
-            {/if}
-            {foreach $dirs as $dir}
-              <tr>
-                <td><a href="{url array('IPF_Admin_FileBrowser_Controller', 'index')}?dir={$curr_dir}{$dir['name']}">{$dir['name']}</a></td>
-                <td>SUB-DIR</td>
-                <td></td>
-                <td>
-                  <form method="POST" action="{url array('IPF_Admin_FileBrowser_Controller', 'delete')}">
-                    <input type="hidden" name="dir" value="{$curr_dir}">
-                    <input type="hidden" name="name" value="{$dir['name']}">
-                    <input type="submit" value="delete" class="link-like">
-                  </form>
-                </td>
-              </tr>
-            {/foreach}
-            {foreach $files as $file}
-              <tr{if $file['type'] === 'image'} class="image"{/if} data-name="{$file['name']}" data-url="{$UPLOAD_URL}{$curr_dir}{$file['name']}">
-                <td><a href="#" class="file">{$file['name']}</a></td>
-                <td>{$file['info']}</td>
-                <td>{$file['size']}</td>
-                <td>
-                  <form method="POST" action="{url array('IPF_Admin_FileBrowser_Controller', 'delete')}">
-                    <input type="hidden" name="dir" value="{$curr_dir}">
-                    <input type="hidden" name="name" value="{$file['name']}">
-                    <input type="submit" value="delete" class="link-like">
-                  </form>
-                </td>
-              </tr>
-            {/foreach}
-            </tbody>
-          </table>
-        </div>
-
-        <div id="prop"><img src="{$zero_gif}"></div>
-
-        <div class="submit-row">
-          <input type="button" disabled class="default select-and-close" value="Select & Close" onclick="FileBrowserSelect()">
-        </div>
-      <!-- /content -->
-    </div>
-  </div>
-
-  <script src="{$STATIC_URL}admin/filebrowser_popup.js"></script>
-</body>
-</html>
-
diff --git a/ipf/admin/templates/admin/filebrowser.html.twig b/ipf/admin/templates/admin/filebrowser.html.twig
new file mode 100644 (file)
index 0000000..905a2ad
--- /dev/null
@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+
+  <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/admin.css">
+  <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/admin-print.css" media="print">
+  <style>
+    html, body {height: 100%;padding:0; margin:0; overflow: hidden;}
+
+    .columns {height: 100%;width:100%;padding:0; margin:0;}
+
+    .sidebar-column {width:250px; height: 100%; border-right:1px dashed #a0a0a0; padding: 0 10px;float: left}
+
+    .hr { border-top:1px dashed #a0a0a0; margin-top:5px; padding-top:5px; }
+
+    .content-column {padding: 0 10px;margin-left:270px;height:100%;}
+    .breadcrumbs {padding:10px 0;height:20px;line-height:20px}
+    .content-column .module {width:100%; height: calc(100% - 90px); overflow:auto; margin: 0;}
+
+    .submit-row {height: 30px;padding: 10px 0; text-align: right;}
+
+    #pic { border:2px solid white; width:240px; text-align:center; height: 150px; line-height: 150px; background: #888; }
+    #pic img { max-width: 240px; max-height: 150px; display:none; }
+
+    #prop { display:none; position:absolute; left:0; top:0; z-index:400000; border:2px solid #aaa; background: #888; }
+    #prop img {max-width:100px;max-height:100px}
+
+    .file-selected {display: none}
+  </style>
+
+  <title>{{ page_title }} - IPF Administration</title>
+</head>
+<body>
+  {% set zero_gif = "data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" %}
+
+  <div class="columns">
+    <div class="sidebar-column">
+      <!-- sidebar -->
+      <form method="post" action="{{ url(['IPF_Admin_FileBrowser_Controller', 'mkdir']) }}">
+        <h3>Add Folder</h3>
+        <input type="hidden" name="dir" value="{{ curr_dir }}">
+        <input name="name">
+        <input type="submit" value="Create">
+      </form>
+
+      <div class="hr"></div>
+
+      <form method="post" enctype="multipart/form-data" action="{{ url(['IPF_Admin_FileBrowser_Controller', 'upload']) }}">
+        <h3>Upload File</h3>
+        <input type="file" name="files[]" multiple="multiple">
+        <input type="hidden" name="dir" value="{{ curr_dir }}">
+        <input type="submit" value="Upload">
+      </form>
+
+      <div class="file-selected">
+        <div class="hr"></div>
+
+        <h3>File Option</h3>
+        <form method="post" action="{{ url(['IPF_Admin_FileBrowser_Controller', 'rename']) }}">
+          <input type="hidden" name="old_name" id="id_old_name">
+          <input type="hidden" name="dir" value="{{ curr_dir }}">
+          <input name="new_name" id="id_new_name">
+          <input type="submit" value="Rename">
+        </form>
+
+        <br>
+
+        <form method="post" action="{{ url(['IPF_Admin_FileBrowser_Controller', 'move']) }}">
+          <input type="hidden" name="name" id="id_old_name2">
+          <input type="hidden" name="dir" value="{{ curr_dir }}">
+          <select name="destination">{% for dir in dirtree %}<option value="{{ dir.path }}">{{ dir.name }}</option>{% endfor %}</select>
+          <input type="submit" value="Move To">
+        </form>
+
+        <div class="hr"></div>
+
+        <h3>View File</h3>
+        <div id="pic"><img src="{{ zero_gif }}"></div>
+      </div>
+      <!-- /sidebar -->
+    </div>
+
+    <div class="content-column">
+      <!-- content -->
+
+        <div class="breadcrumbs">
+          <a href="{{ url(['IPF_Admin_FileBrowser_Controller', 'index']) }}?dir=">Root</a>
+          {% for p in path %}
+            / <a href="{{ url(['IPF_Admin_FileBrowser_Controller', 'index']) }}?dir={{ p.dir }}">{{ p.name }}</a>
+          {% endfor %}
+        </div>
+
+        <div class="module" id="changelist">
+          <table>
+            <thead>
+              <tr>
+                <th>Name</th>
+                <th>Type</th>
+                <th>Size</th>
+                <th>Delete</th>
+              </tr>
+            </thead>
+            <tbody>
+            {% if curr_dir %}
+              <tr>
+                <td><a href="{{ url(['IPF_Admin_FileBrowser_Controller', 'index']) }}?dir={{ parent_dir }}">..</a></td>
+                <td>UP-DIR</td>
+                <td></td>
+                <td></td>
+              </tr>
+            {% endif %}
+            {% for dir in dirs %}
+              <tr>
+                <td><a href="{{ url(['IPF_Admin_FileBrowser_Controller', 'index']) }}?dir={{ curr_dir }}{{ dir.name }}">{{ dir.name }}</a></td>
+                <td>SUB-DIR</td>
+                <td></td>
+                <td>
+                  <form method="POST" action="{{ url(['IPF_Admin_FileBrowser_Controller', 'delete']) }}">
+                    <input type="hidden" name="dir" value="{{ curr_dir }}">
+                    <input type="hidden" name="name" value="{{ dir.name }}">
+                    <input type="submit" value="delete" class="link-like">
+                  </form>
+                </td>
+              </tr>
+            {% endfor %}
+            {% for file in files %}
+              <tr{% if file.type == 'image' %} class="image"{% endif %} data-name="{{ file.name }}" data-url="{{ UPLOAD_URL }}{{ curr_dir }}{{ file.name }}">
+                <td><a href="#" class="file">{{ file.name }}</a></td>
+                <td>{{ file.info }}</td>
+                <td>{{ file.size }}</td>
+                <td>
+                  <form method="POST" action="{{ url(['IPF_Admin_FileBrowser_Controller', 'delete']) }}">
+                    <input type="hidden" name="dir" value="{{ curr_dir }}">
+                    <input type="hidden" name="name" value="{{ file.name }}">
+                    <input type="submit" value="delete" class="link-like">
+                  </form>
+                </td>
+              </tr>
+            {% endfor %}
+            </tbody>
+          </table>
+        </div>
+
+        <div id="prop"><img src="{{ zero_gif }}"></div>
+
+        <div class="submit-row">
+          <input type="button" disabled class="default select-and-close" value="Select & Close" onclick="FileBrowserSelect()">
+        </div>
+      <!-- /content -->
+    </div>
+  </div>
+
+  <script src="{{ STATIC_URL }}admin/filebrowser_popup.js"></script>
+</body>
+</html>
diff --git a/ipf/admin/templates/admin/index.html b/ipf/admin/templates/admin/index.html
deleted file mode 100644 (file)
index 88f673b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-{extends "admin/base.html"}
-
-{block sidebar_toggle}{/block}
-{block navigation}{/block}
-
-{block content}
-<div id="content" class="colMS dashboard">
-    <h1>{$page_title}</h1>
-    <div id="content-main">
-        {foreach $app_list() as $app}
-               <div class="module">
-        <table summary="">
-        <caption>{$app.name|escxml}</caption>
-               <tbody>
-        {foreach $app.components as $component}
-        <tr>
-            <th scope="row"><a href="{url array('IPF_Admin_Components_Controller', 'listItems'), array($app.path, $component->slug)}">{$component->name}</a></th>
-            <td>{if $component->can_add}<a class="addlink" href="{url array('IPF_Admin_Components_Controller', 'addItem'), array($app.path, $component->slug)}">{trans 'Add'}</a>{/if}</td>
-            <td><a class="changelink" href="{url array('IPF_Admin_Components_Controller', 'listItems'), array($app.path, $component->slug)}">{trans 'Change'}</a></td>
-        </tr>
-        {/foreach}
-        </tbody>
-        </table>
-               </div>
-        {/foreach}
-    </div>
-    <div id="content-related">
-        <div class="module">
-            <h2>{trans 'Recent Actions'}</h2>
-            <ul class="actionlist">
-            {foreach $admin_log as $log}
-            <li class="{$log.action}link">
-              {if $log.object_url}
-                <a href="{$log.object_url}">{$log.object_repr}</a>
-              {else}
-                {$log.object_repr}
-              {/if}
-              <br><span class="mini quiet">{$log.object_class} at {$log.created_at|date} by {$log.username}</span>
-            </li>
-            {/foreach}
-            </ul>
-            <a class="all" href="{url array('IPF_Admin_Dashboard_Controller', 'log')}">{trans 'View all'}</a>
-        </div>
-    </div>
-    <br class="clear" />
-</div>
-{/block}
-
diff --git a/ipf/admin/templates/admin/index.html.twig b/ipf/admin/templates/admin/index.html.twig
new file mode 100644 (file)
index 0000000..bfc9f59
--- /dev/null
@@ -0,0 +1,47 @@
+{% extends "admin/base.html.twig" %}
+
+{% block sidebar_toggle %}{% endblock %}
+{% block navigation %}{% endblock %}
+
+{% block content %}
+<div id="content" class="colMS dashboard">
+    <h1>{{ page_title }}</h1>
+    <div id="content-main">
+        {% for app in app_list %}
+               <div class="module">
+        <table summary="">
+        <caption>{{ app.name }}</caption>
+               <tbody>
+        {% for component in app.components %}
+        <tr>
+            <th scope="row"><a href="{{ url(['IPF_Admin_Components_Controller', 'listItems'], [app.path, component.slug]) }}">{{ component.name }}</a></th>
+            <td>{% if component.can_add %}<a class="addlink" href="{{ url(['IPF_Admin_Components_Controller', 'addItem'], [app.path, component.slug]) }}">{{ trans('Add') }}</a>{% endif %}</td>
+            <td><a class="changelink" href="{{ url(['IPF_Admin_Components_Controller', 'listItems'], [app.path, component.slug]) }}">{{ trans('Change') }}</a></td>
+        </tr>
+        {% endfor %}
+        </tbody>
+        </table>
+               </div>
+        {% endfor %}
+    </div>
+    <div id="content-related">
+        <div class="module">
+            <h2>{{ trans('Recent Actions') }}</h2>
+            <ul class="actionlist">
+            {% for log in admin_log %}
+            <li class="{{ log.action }}link">
+              {% if log.object_url %}
+                <a href="{{ log.object_url }}">{{ log.object_repr }}</a>
+              {% else %}
+                {{ log.object_repr }}
+              {% endif %}
+              <br><span class="mini quiet">{{ log.object_class }} at {{ log.created_at|date }} by {{ log.username }}</span>
+            </li>
+            {% endfor %}
+            </ul>
+            <a class="all" href="{{ url(['IPF_Admin_Dashboard_Controller', 'log']) }}">{{ trans('View all') }}</a>
+        </div>
+    </div>
+    <br class="clear" />
+</div>
+{% endblock %}
diff --git a/ipf/admin/templates/admin/items.html b/ipf/admin/templates/admin/items.html
deleted file mode 100644 (file)
index 6b48a6d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-{extends "admin/base.html"}
-
-{block breadcrumbs}<div class="breadcrumbs"><a href="{url array('IPF_Admin_Dashboard_Controller', 'index')}">{trans 'Home'}</a> &raquo; {$page_title}</div>{/block}
-
-{block content}
-<div id="content" class="flex">
-  <h1>{$page_title}</h1>
-  <div id="content-main">
-    <ul class="object-tools">
-      {block objecttools}
-      {if $can_add}<li><a href="add/">{$title_add}</a></li>{/if}
-      <li><a href="javascript:print();">{trans 'Print'}</a></li>
-      {/block}
-    </ul>
-    <div id="changelist" class="module {if $filters} filtered{/if}">
-      {if $is_search}
-      <div id="toolbar">
-        <form id="changelist-search" method="get" action="">
-          <div>
-            {foreach $request->GET as $k => $v}
-              {if $k !== 'q'}
-                <input type="hidden" name="{$k}" value="{$v}">
-              {/if}
-            {/foreach}
-            <label for="searchbar">
-              <img alt="Search" src="{$STATIC_URL}admin/img/search.svg">
-            </label>
-            <input id="searchbar" type="text" value="{$search_value}" name="q" size="40"/>
-            <input type="submit" value="Go"/>
-            {if $search_value}
-            <span class="small quiet">{$count} results (<a href="?{params $request->GET, 'q', null}">reset</a>)</span>
-            {/if}
-          </div>
-        </form>
-      </div>
-      {/if}
-
-      {if $filters}
-      <div id="changelist-filter">
-        <h2>Filter</h2>
-        {foreach $filters as $f}
-          <h3>{$f->title()}</h3>
-          {$component->renderFilter($f)|safe}
-        {/foreach}
-      </div>
-      {/if}
-
-      <div id="items-grid-container">
-        {block table}
-        <table id="items-grid"{if $orderable} class="reorderable"{/if}>
-          <thead>
-            <tr class="nodrop">
-              {foreach $header as $h}
-              <th>{$h['title']}</th>
-              {/foreach}
-            </tr>
-          </thead>
-          <tbody>
-            {foreach $rows as $row}
-            <tr class="trsort" id="{$row['object_id']}">
-              {foreach $row['cells'] as $cell}
-              <td>{$cell|safe}</td>
-              {/foreach}
-            </tr>
-            {/foreach}
-          </tbody>
-        </table>
-        {/block}
-        <p class="paginator">
-          {foreach $pages as $p}
-            {if $p}
-              {if $p == $current_page}
-                <span class="this-page">{$p}</span>
-              {else}
-                <a href="?{params $request->GET, 'page', $p}">{$p}</a>
-              {/if}
-            {else}
-              &hellip;
-            {/if}
-          {/foreach}
-          {$count} record(s) of {$classname}
-        </p>
-      </div>
-
-    </div>
-  </div>
-  <br class="clear" />
-</div>
-{/block}
-
diff --git a/ipf/admin/templates/admin/items.html.twig b/ipf/admin/templates/admin/items.html.twig
new file mode 100644 (file)
index 0000000..233cccf
--- /dev/null
@@ -0,0 +1,89 @@
+{% extends "admin/base.html.twig" %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="{{ url(['IPF_Admin_Dashboard_Controller', 'index']) }}">{{ trans('Home') }}</a> &raquo; {{ page_title }}</div>{% endblock %}
+
+{% block content %}
+<div id="content" class="flex">
+  <h1>{{ page_title }}</h1>
+  <div id="content-main">
+    <ul class="object-tools">
+      {% block objecttools %}
+      {% if can_add %}<li><a href="add/">{{ title_add }}</a></li>{% endif %}
+      <li><a href="javascript:print();">{{ trans('Print') }}</a></li>
+      {% endblock %}
+    </ul>
+    <div id="changelist" class="module {% if filters %} filtered{% endif %}">
+      {% if is_search %}
+      <div id="toolbar">
+        <form id="changelist-search" method="get" action="">
+          <div>
+            {% for k, v in request.GET %}
+              {% if k != 'q' %}
+                <input type="hidden" name="{{ k }}" value="{{ v }}">
+              {% endif %}
+            {% endfor %}
+            <label for="searchbar">
+              <img alt="Search" src="{{ STATIC_URL }}admin/img/search.svg">
+            </label>
+            <input id="searchbar" type="text" value="{{ search_value }}" name="q" size="40"/>
+            <input type="submit" value="Go"/>
+            {% if search_value %}
+            <span class="small quiet">{{ count }} results (<a href="?{{ params(request.GET, 'q', null) }}">reset</a>)</span>
+            {% endif %}
+          </div>
+        </form>
+      </div>
+      {% endif %}
+
+      {% if filters %}
+      <div id="changelist-filter">
+        <h2>Filter</h2>
+        {% for f in filters %}
+          <h3>{{ f.title }}</h3>
+          {{ component.renderFilter(f)|raw }}
+        {% endfor %}
+      </div>
+      {% endif %}
+
+      <div id="items-grid-container">
+        {% block table %}
+        <table id="items-grid"{% if orderable %} class="reorderable"{% endif %}>
+          <thead>
+            <tr class="nodrop">
+              {% for h in header %}
+              <th>{{ h.title }}</th>
+              {% endfor %}
+            </tr>
+          </thead>
+          <tbody>
+            {% for row in rows %}
+            <tr class="trsort" id="{{ row.object_id }}">
+              {% for cell in row.cells %}
+              <td>{{ cell|raw }}</td>
+              {% endfor %}
+            </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+        {% endblock %}
+        <p class="paginator">
+          {% for p in pages %}
+            {% if p %}
+              {% if p == current_page %}
+                <span class="this-page">{{ p }}</span>
+              {% else %}
+                <a href="?{{ params(request.GET, 'page', p) }}">{{ p }}</a>
+              {% endif %}
+            {% else %}
+              &hellip;
+            {% endif %}
+          {% endfor %}
+          {{ count }} record(s) of {{ classname }}
+        </p>
+      </div>
+
+    </div>
+  </div>
+  <br class="clear" />
+</div>
+{% endblock %}
diff --git a/ipf/admin/templates/admin/log.html b/ipf/admin/templates/admin/log.html
deleted file mode 100644 (file)
index 74f7413..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-{extends "admin/base.html"}
-
-{block breadcrumbs}<div class="breadcrumbs"><a href="{url array('IPF_Admin_Dashboard_Controller', 'index')}">{trans 'Home'}</a> &raquo; {$page_title}</div>{/block}
-
-{block content}
-<div id="content" class="flex">
-  <h1>{$page_title}</h1>
-  <div id="content-main">
-    <div id="changelist" class="module">
-
-      <div id="items-grid-container">
-        <table id="items-grid">
-          <thead>
-            <tr class="nodrop">
-              <th>{trans 'Action'}</th>
-              <th>{trans 'Type'}</th>
-              <th>{trans 'When'}</th>
-              <th>{trans 'Who'}</th>
-            </tr>
-          </thead>
-          <tbody>
-            {foreach $admin_log as $log}
-            <tr>
-              <td class="{$log.action}link">
-                {if $log.object_url}
-                  <a href="{$log.object_url}">{$log.object_repr}</a>
-                {else}
-                  {$log.object_repr}
-                {/if}
-              </td>
-              <td>{$log.object_class}</td>
-              <td>{$log.created_at|datetime:'%b %e, %Y %H:%M:%S'}</td>
-              <td>{$log.username}</td>
-            </tr>
-            {/foreach}
-          </tbody>
-        </table>
-
-        <p class="paginator">
-          {foreach $pages as $p}
-            {if $p}
-              {if $p == $current_page}
-                <span class="this-page">{$p}</span>
-              {else}
-                <a href="?{params $request->GET, 'page', $p}">{$p}</a>
-              {/if}
-            {else}
-              &hellip;
-            {/if}
-          {/foreach}
-          {$count} log records
-        </p>
-      </div>
-
-    </div>
-  </div>
-  <br class="clear" />
-</div>
-{/block}
-
diff --git a/ipf/admin/templates/admin/log.html.twig b/ipf/admin/templates/admin/log.html.twig
new file mode 100644 (file)
index 0000000..59e05fd
--- /dev/null
@@ -0,0 +1,59 @@
+{% extends "admin/base.html.twig" %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="{{ url(['IPF_Admin_Dashboard_Controller', 'index']) }}">{{ trans('Home') }}</a> &raquo; {{ page_title }}</div>{% endblock %}
+
+{% block content %}
+<div id="content" class="flex">
+  <h1>{{ page_title }}</h1>
+  <div id="content-main">
+    <div id="changelist" class="module">
+
+      <div id="items-grid-container">
+        <table id="items-grid">
+          <thead>
+            <tr class="nodrop">
+              <th>{{ trans('Action') }}</th>
+              <th>{{ trans('Type') }}</th>
+              <th>{{ trans('When') }}</th>
+              <th>{{ trans('Who') }}</th>
+            </tr>
+          </thead>
+          <tbody>
+            {% for log in admin_log %}
+            <tr>
+              <td class="{{ log.action }}link">
+                {% if log.object_url %}
+                  <a href="{{ log.object_url }}">{{ log.object_repr }}</a>
+                {% else %}
+                  {{ log.object_repr }}
+                {% endif %}
+              </td>
+              <td>{{ log.object_class }}</td>
+              <td>{{ log.created_at|date('M j, Y H:i:s') }}</td>
+              <td>{{ log.username }}</td>
+            </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+
+        <p class="paginator">
+          {% for p in pages %}
+            {% if p %}
+              {% if p == current_page %}
+                <span class="this-page">{{ p }}</span>
+              {% else %}
+                <a href="?{{ params(request.GET, 'page', p) }}">{{ p }}</a>
+              {% endif %}
+            {% else %}
+              &hellip;
+            {% endif %}
+          {% endfor %}
+          {{ count }} log records
+        </p>
+      </div>
+
+    </div>
+  </div>
+  <br class="clear" />
+</div>
+{% endblock %}
diff --git a/ipf/admin/templates/admin/login.html b/ipf/admin/templates/admin/login.html
deleted file mode 100644 (file)
index 674eea0..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  {block css}
-  <link rel="stylesheet" type="text/css" href="{$STATIC_URL}admin/login.css" />
-  {/block}
-  <title>{$page_title}</title>
-</head>
-
-<body>
-
-<div id="container">
-  <h1><a href="{$indexpage_url}">{$admin_title}</a></h1>
-
-  <div id="content">
-    <form method="post">
-      {$form->render()|safe}
-      <input type="submit" value="Sign In">
-    </form>
-  </div>
-</div>
-
-<script>document.getElementById('id_username').focus();</script>
-</body>
-</html>
-
diff --git a/ipf/admin/templates/admin/login.html.twig b/ipf/admin/templates/admin/login.html.twig
new file mode 100644 (file)
index 0000000..7069466
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  {% block css %}
+  <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/login.css" />
+  {% endblock %}
+  <title>{{ page_title }}</title>
+</head>
+
+<body>
+
+<div id="container">
+  <h1><a href="{{ indexpage_url }}">{{ admin_title }}</a></h1>
+
+  <div id="content">
+    <form method="post">
+      {{ form.render()|raw }}
+      <input type="submit" value="Sign In">
+    </form>
+  </div>
+</div>
+
+<script>document.getElementById('id_username').focus();</script>
+</body>
+</html>
diff --git a/ipf/admin/templates/admin/logout.html b/ipf/admin/templates/admin/logout.html
deleted file mode 100644 (file)
index bb2eda2..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{extends 'admin/base.html'}
-
-{block sidebar_toggle}{/block}
-{block navigation}{/block}
-
-{block content}
-<div id="content" class="colM">
-<h1>Logged out</h1>
-<p>Thanks for spending some quality time with the Web site today.</p>
-<p><a href="{url array('IPF_Admin_Dashboard_Controller', 'index')}">Log in</a> again.</p>
-<br class="clear"/>
-</div>
-{/block}
-
diff --git a/ipf/admin/templates/admin/logout.html.twig b/ipf/admin/templates/admin/logout.html.twig
new file mode 100644 (file)
index 0000000..263a137
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends 'admin/base.html.twig' %}
+
+{% block sidebar_toggle %}{% endblock %}
+{% block navigation %}{% endblock %}
+
+{% block content %}
+<div id="content" class="colM">
+<h1>Logged out</h1>
+<p>Thanks for spending some quality time with the Web site today.</p>
+<p><a href="{{ url(['IPF_Admin_Dashboard_Controller', 'index']) }}">Log in</a> again.</p>
+<br class="clear"/>
+</div>
+{% endblock %}
index 1d406bd116dcc82694756a8a7167520b4c7a9f1b..3cbb43d5426267002f319f2ac533acc42138aa80 100644 (file)
@@ -94,4 +94,3 @@ final class IPF_Project_Template
         return IPF_HTTP_URL::generateParams($params);
     }
 }
-
diff --git a/ipf/twig.php b/ipf/twig.php
new file mode 100644 (file)
index 0000000..e68b6a2
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+final class IPF_Twig
+{
+    public static function render($tplfile, $params=array(), $request=null)
+    {
+        $context = IPF_Project_Template::context($params, $request);
+        $twig = self::createEnvironment();
+        $template = $twig->loadTemplate($tplfile);
+        return $template->render($context);
+    }
+
+    private static function createEnvironment()
+    {
+        $options = array(
+            'cache' => IPF::get('tmp'),
+        );
+        if (IPF::get('debug')) {
+            $options['debug'] = true;
+            $options['auto_reload'] = true;
+        }
+
+        $twig = new Twig_Environment(self::createLoader(), $options);
+
+        $twig->addFunction(new Twig_SimpleFunction('url', function() {
+            return IPF_Project_Template::urlTag(func_get_args());
+        }));
+        $twig->addFunction(new Twig_SimpleFunction('params', function() {
+            return IPF_Project_Template::paramsTag(func_get_args());
+        }));
+        $twig->addFunction(new Twig_SimpleFunction('trans', function($str) {
+            return __($str);
+        }));
+
+        return $twig;
+    }
+
+    private static function createLoader()
+    {
+        $loader = new Twig_Loader_Filesystem(array());
+        foreach (IPF_Project_Template::templateDirs() as $dir) {
+            $loader->addPath($dir);
+        }
+        return $loader;
+    }
+}