From 37a62bb6443a04273641ce30a463f2fe3a2193cd Mon Sep 17 00:00:00 2001
From: Marcus Eibrink-Lunzenauer <gitlab+elanev@luniki.de>
Date: Fri, 26 Nov 2021 11:32:24 +0100
Subject: [PATCH] Add templates

---
 .../StandardPlugin/implements.ejs.t           |  7 ++
 .../StandardPlugin/methods.ejs.t              | 78 +++++++++++++++++++
 .../add-interface/StandardPlugin/prompt.js    | 39 ++++++++++
 _templates/generator/help/index.ejs.t         |  5 ++
 _templates/generator/new/hello.ejs.t          | 18 +++++
 _templates/generator/with-prompt/hello.ejs.t  | 18 +++++
 _templates/generator/with-prompt/prompt.ejs.t | 16 ++++
 _templates/plugin/add/hello.ejs.t             | 21 +++++
 _templates/plugin/add/prompt.js               | 30 +++++++
 _templates/plugin/add/standard.ejs.t          | 65 ++++++++++++++++
 _templates/plugin/add/system.ejs.t            |  6 ++
 _templates/plugin/trails/prompt.js            | 34 ++++++++
 .../plugin/trails/trails.ejs.t                | 25 ++----
 .../plugin/trails/trailsController.ejs.t      | 15 ++++
 _templates/plugin/trails/trailsView.ejs.t     |  5 ++
 _templates/trails/action/hello.ejs.t          | 15 ++++
 _templates/trails/controller/hello.ejs.t      | 15 ++++
 17 files changed, 393 insertions(+), 19 deletions(-)
 create mode 100644 _templates/add-interface/StandardPlugin/implements.ejs.t
 create mode 100644 _templates/add-interface/StandardPlugin/methods.ejs.t
 create mode 100644 _templates/add-interface/StandardPlugin/prompt.js
 create mode 100644 _templates/generator/help/index.ejs.t
 create mode 100644 _templates/generator/new/hello.ejs.t
 create mode 100644 _templates/generator/with-prompt/hello.ejs.t
 create mode 100644 _templates/generator/with-prompt/prompt.ejs.t
 create mode 100644 _templates/plugin/add/hello.ejs.t
 create mode 100644 _templates/plugin/add/prompt.js
 create mode 100644 _templates/plugin/add/standard.ejs.t
 create mode 100644 _templates/plugin/add/system.ejs.t
 create mode 100644 _templates/plugin/trails/prompt.js
 rename ExamplePlugin.php => _templates/plugin/trails/trails.ejs.t (73%)
 create mode 100644 _templates/plugin/trails/trailsController.ejs.t
 create mode 100644 _templates/plugin/trails/trailsView.ejs.t
 create mode 100644 _templates/trails/action/hello.ejs.t
 create mode 100644 _templates/trails/controller/hello.ejs.t

diff --git a/_templates/add-interface/StandardPlugin/implements.ejs.t b/_templates/add-interface/StandardPlugin/implements.ejs.t
new file mode 100644
index 0000000..7e42f25
--- /dev/null
+++ b/_templates/add-interface/StandardPlugin/implements.ejs.t
@@ -0,0 +1,7 @@
+---
+inject: true
+to: <%= pluginclassname %>
+skip_if: StandardPlugin,
+after: \/\* Plugin Interfaces \*\/
+---
+    StandardPlugin,
\ No newline at end of file
diff --git a/_templates/add-interface/StandardPlugin/methods.ejs.t b/_templates/add-interface/StandardPlugin/methods.ejs.t
new file mode 100644
index 0000000..7a81c88
--- /dev/null
+++ b/_templates/add-interface/StandardPlugin/methods.ejs.t
@@ -0,0 +1,78 @@
+---
+inject: true
+to: <%= pluginclassname %>
+skip_if: getInfoTemplate|getIconNavigation|getTabNavigation|getMetadata
+after: \/\* Interface Methods \*\/
+---
+    /**
+     * Return a template (an instance of the Flexi_Template class)
+     * to be rendered on the course summary page. Return NULL to
+     * render nothing for this plugin.
+     *
+     * The template will automatically get a standard layout, which
+     * can be configured via attributes set on the template:
+     *
+     *  title        title to display, defaults to plugin name
+     *  icon_url     icon for this plugin (if any)
+     *  admin_url    admin link for this plugin (if any)
+     *  admin_title  title for admin link (default: Administration)
+     *
+     * @return object   template object to render or NULL
+     */
+    function getInfoTemplate($course_id)
+    {
+        return null;
+    }
+
+    /**
+     * Return a navigation object representing this plugin in the
+     * course overview table or return NULL if you want to display
+     * no icon for this plugin (or course). The navigation object's
+     * title will not be shown, only the image (and its associated
+     * attributes like 'title') and the URL are actually used.
+     *
+     * By convention, new or changed plugin content is indicated
+     * by a different icon and a corresponding tooltip.
+     *
+     * @param  string   $course_id   course or institute range id
+     * @param  int      $last_visit  time of user's last visit
+     * @param  string   $user_id     the user to get the navigation for
+     *
+     * @return object   navigation item to render or NULL
+     */
+    function getIconNavigation($course_id, $last_visit, $user_id)
+    {
+        return null;
+    }
+
+    /**
+     * Return a navigation object representing this plugin in the
+     * course overview table or return NULL if you want to display
+     * no icon for this plugin (or course). The navigation object's
+     * title will not be shown, only the image (and its associated
+     * attributes like 'title') and the URL are actually used.
+     *
+     * By convention, new or changed plugin content is indicated
+     * by a different icon and a corresponding tooltip.
+     *
+     * @param  string   $course_id   course or institute range id
+     *
+     * @return array    navigation item to render or NULL
+     */
+    function getTabNavigation($course_id)
+    {
+        return null;
+    }
+
+
+    /**
+     * Provides metadata like a descriptional text for this module that
+     * is shown on the course "+" page to inform users about what the
+     * module acutally does. Additionally, a URL can be specified.
+     *
+     * @return array    metadata containg description and/or url
+     */
+    function getMetadata()
+    {
+        return [];
+    }
diff --git a/_templates/add-interface/StandardPlugin/prompt.js b/_templates/add-interface/StandardPlugin/prompt.js
new file mode 100644
index 0000000..b803c5e
--- /dev/null
+++ b/_templates/add-interface/StandardPlugin/prompt.js
@@ -0,0 +1,39 @@
+const fs = require("fs");
+const path = require("path");
+
+module.exports = [
+  {
+    type: "list",
+    name: "pluginclassname",
+    message: "Welche Plugin-Klasse?",
+    choices: function() {
+      const pluginDirectory = path.join(__dirname, "../../..");
+      const manifestFilename = pluginDirectory + "/plugin.manifest";
+
+      const manifest = fs.readFileSync(manifestFilename, "utf-8");
+      const result = manifest.match(/^pluginclassname=.*/gm);
+
+      if (!result) {
+        return null;
+      }
+
+      const x = result.reduce((memo, item) => {
+        const pluginClassname = item.substr("pluginclassname=".length);
+        console.log(pluginClassname);
+        const oldStyle = pluginClassname + ".class.php";
+        const newStyle = pluginClassname + ".php";
+        if (fs.existsSync(path.join(pluginDirectory, oldStyle))) {
+          memo.push(oldStyle);
+        } else if (fs.existsSync(path.join(pluginDirectory, newStyle))) {
+          memo.push(newStyle);
+        }
+
+        return memo;
+      }, []);
+
+      console.log(x);
+
+      return x;
+    }
+  }
+];
diff --git a/_templates/generator/help/index.ejs.t b/_templates/generator/help/index.ejs.t
new file mode 100644
index 0000000..90a29af
--- /dev/null
+++ b/_templates/generator/help/index.ejs.t
@@ -0,0 +1,5 @@
+---
+message: |
+  hygen {bold generator new} --name [NAME] --action [ACTION]
+  hygen {bold generator with-prompt} --name [NAME] --action [ACTION]
+---
\ No newline at end of file
diff --git a/_templates/generator/new/hello.ejs.t b/_templates/generator/new/hello.ejs.t
new file mode 100644
index 0000000..5680d96
--- /dev/null
+++ b/_templates/generator/new/hello.ejs.t
@@ -0,0 +1,18 @@
+---
+to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
+---
+---
+to: app/hello.js
+---
+const hello = ```
+Hello!
+This is your first hygen template.
+
+Learn what it can do here:
+
+https://github.com/jondot/hygen
+```
+
+console.log(hello)
+
+
diff --git a/_templates/generator/with-prompt/hello.ejs.t b/_templates/generator/with-prompt/hello.ejs.t
new file mode 100644
index 0000000..ba6abc5
--- /dev/null
+++ b/_templates/generator/with-prompt/hello.ejs.t
@@ -0,0 +1,18 @@
+---
+to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
+---
+---
+to: app/hello.js
+---
+const hello = ```
+Hello!
+This is your first prompt based hygen template.
+
+Learn what it can do here:
+
+https://github.com/jondot/hygen
+```
+
+console.log(hello)
+
+
diff --git a/_templates/generator/with-prompt/prompt.ejs.t b/_templates/generator/with-prompt/prompt.ejs.t
new file mode 100644
index 0000000..d5984a5
--- /dev/null
+++ b/_templates/generator/with-prompt/prompt.ejs.t
@@ -0,0 +1,16 @@
+---
+to: _templates/<%= name %>/<%= action || 'new' %>/prompt.js
+---
+
+// see types of prompts:
+// https://github.com/SBoudrias/Inquirer.js#prompt-types
+//
+// and for examples for prompts:
+// https://github.com/SBoudrias/Inquirer.js/tree/master/examples
+module.exports = [
+  {
+    type: 'input',
+    name: 'message',
+    message: "What's your message?"
+  }
+]
diff --git a/_templates/plugin/add/hello.ejs.t b/_templates/plugin/add/hello.ejs.t
new file mode 100644
index 0000000..86c0af3
--- /dev/null
+++ b/_templates/plugin/add/hello.ejs.t
@@ -0,0 +1,21 @@
+---
+to: <%= pluginclassname %>.php
+---
+<?php
+
+/**
+ * Stud.IP plugin.
+ */
+class <%= pluginclassname %> extends StudIPPlugin implements
+    /* Plugin Interfaces */
+    <%= plugininterfaces.join(",\n    ") %>
+{
+    public function __construct()
+    {
+        parent::__construct();
+
+        require_once 'vendor/autoload.php';
+    }
+
+    /* Interface Methods */
+}
diff --git a/_templates/plugin/add/prompt.js b/_templates/plugin/add/prompt.js
new file mode 100644
index 0000000..c374364
--- /dev/null
+++ b/_templates/plugin/add/prompt.js
@@ -0,0 +1,30 @@
+const fs = require("fs");
+const path = require("path");
+
+module.exports = [
+  {
+    type: "input",
+    name: "pluginclassname",
+    message: "Wie soll die Plugin-Klasse heißen?",
+    validate: function(input) {
+      if (input.match(/^[A-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/)) {
+        return true;
+      }
+
+      return "Ungültiger Klassenname";
+    }
+  },
+  {
+    type: "checkbox",
+    name: "plugininterfaces",
+    message: "Welche Plugin-Interface?",
+    choices: ["StandardPlugin", "SystemPlugin"],
+    validate: function(input) {
+      if (input.length) {
+        return true;
+      }
+
+      return "Mindestens ein Plugin-Interface muss gewählt sein.";
+    }
+  }
+];
diff --git a/_templates/plugin/add/standard.ejs.t b/_templates/plugin/add/standard.ejs.t
new file mode 100644
index 0000000..e448537
--- /dev/null
+++ b/_templates/plugin/add/standard.ejs.t
@@ -0,0 +1,65 @@
+---
+inject: true
+to: <%= pluginclassname %>.php
+skip_if: getInfoTemplate
+after: \/\* Interface Methods \*\/
+---
+    /**
+     * Return a template (an instance of the Flexi_Template class)
+     * to be rendered on the course summary page. Return NULL to
+     * render nothing for this plugin.
+     *
+     * The template will automatically get a standard layout, which
+     * can be configured via attributes set on the template:
+     *
+     *  title        title to display, defaults to plugin name
+     *  icon_url     icon for this plugin (if any)
+     *  admin_url    admin link for this plugin (if any)
+     *  admin_title  title for admin link (default: Administration)
+     *
+     * @return object   template object to render or NULL
+     */
+    function getInfoTemplate($course_id)
+    {
+        return null;
+    }
+
+    /**
+     * Return a navigation object representing this plugin in the
+     * course overview table or return NULL if you want to display
+     * no icon for this plugin (or course). The navigation object's
+     * title will not be shown, only the image (and its associated
+     * attributes like 'title') and the URL are actually used.
+     *
+     * By convention, new or changed plugin content is indicated
+     * by a different icon and a corresponding tooltip.
+     *
+     * @param string $course_id  course or institute range id
+     * @param int    $last_visit time of user's last visit
+     * @param string $user_id    the user to get the navigation for
+     *
+     * @return object navigation item to render or NULL
+     */
+    public function getIconNavigation($course_id, $last_visit, $user_id)
+    {
+        return null;
+    }
+
+    /**
+     * Return a navigation object representing this plugin in the
+     * course overview table or return NULL if you want to display
+     * no icon for this plugin (or course). The navigation object's
+     * title will not be shown, only the image (and its associated
+     * attributes like 'title') and the URL are actually used.
+     *
+     * By convention, new or changed plugin content is indicated
+     * by a different icon and a corresponding tooltip.
+     *
+     * @param string $course_id course or institute range id
+     *
+     * @return array navigation item to render or NULL
+     */
+    public function getTabNavigation($course_id)
+    {
+        return null;
+    }
diff --git a/_templates/plugin/add/system.ejs.t b/_templates/plugin/add/system.ejs.t
new file mode 100644
index 0000000..275f96d
--- /dev/null
+++ b/_templates/plugin/add/system.ejs.t
@@ -0,0 +1,6 @@
+---
+inject: true
+to: <%= pluginclassname %>.php
+xskip_if: SystemPlugin,
+after: \/\* Interface Methods \*\/
+---
diff --git a/_templates/plugin/trails/prompt.js b/_templates/plugin/trails/prompt.js
new file mode 100644
index 0000000..28ca77b
--- /dev/null
+++ b/_templates/plugin/trails/prompt.js
@@ -0,0 +1,34 @@
+const fs = require("fs");
+const path = require("path");
+
+module.exports = [
+  {
+    type: "list",
+    name: "pluginclassname",
+    message: "Welche Plugin-Klasse?",
+    choices: function() {
+      const pluginDirectory = path.join(__dirname, "../../..");
+      const manifestFilename = pluginDirectory + "/plugin.manifest";
+
+      const manifest = fs.readFileSync(manifestFilename, "utf-8");
+      const result = manifest.match(/^pluginclassname=.*/gm);
+
+      if (!result) {
+        return null;
+      }
+
+      return result.reduce((memo, item) => {
+        const pluginClassname = item.substr("pluginclassname=".length);
+        const oldStyle = pluginClassname + ".class.php";
+        const newStyle = pluginClassname + ".php";
+        if (fs.existsSync(path.join(pluginDirectory, oldStyle))) {
+          memo.push(oldStyle);
+        } else if (fs.existsSync(path.join(pluginDirectory, newStyle))) {
+          memo.push(newStyle);
+        }
+
+        return memo;
+      }, []);
+    }
+  }
+];
diff --git a/ExamplePlugin.php b/_templates/plugin/trails/trails.ejs.t
similarity index 73%
rename from ExamplePlugin.php
rename to _templates/plugin/trails/trails.ejs.t
index 8eea4f4..17dc276 100644
--- a/ExamplePlugin.php
+++ b/_templates/plugin/trails/trails.ejs.t
@@ -1,19 +1,9 @@
-<?php
-
-/**
- * Example Stud.IP plugin.
- */
-class ExamplePlugin extends StudIPPlugin implements
-    /* Plugin Interfaces */
-    SystemPlugin
-{
-    public function __construct()
-    {
-        parent::__construct();
-
-        require_once 'vendor/autoload.php';
-    }
-
+---
+inject: true
+to: <%= pluginclassname %>
+skip_if: perform
+before: \/\* Interface Methods \*\/
+---
     /**
      * This method dispatches all actions.
      *
@@ -39,6 +29,3 @@ class ExamplePlugin extends StudIPPlugin implements
             }
         }
     }
-
-    /* Interface Methods */
-}
diff --git a/_templates/plugin/trails/trailsController.ejs.t b/_templates/plugin/trails/trailsController.ejs.t
new file mode 100644
index 0000000..3647b27
--- /dev/null
+++ b/_templates/plugin/trails/trailsController.ejs.t
@@ -0,0 +1,15 @@
+---
+to: controllers/index.php
+---
+<?php
+
+class IndexController extends \StudipController
+{
+    public function before_filter(&$action, &$args)
+    {
+    }
+
+    protected function index_url()
+    {
+    }
+}
diff --git a/_templates/plugin/trails/trailsView.ejs.t b/_templates/plugin/trails/trailsView.ejs.t
new file mode 100644
index 0000000..f7559d1
--- /dev/null
+++ b/_templates/plugin/trails/trailsView.ejs.t
@@ -0,0 +1,5 @@
+---
+to: views/index/index.php
+---
+<h1>Hallo, Welt!</h1>
+<p>Find me in {pluginDirectory}/views/index/index.php</p>
diff --git a/_templates/trails/action/hello.ejs.t b/_templates/trails/action/hello.ejs.t
new file mode 100644
index 0000000..095a04e
--- /dev/null
+++ b/_templates/trails/action/hello.ejs.t
@@ -0,0 +1,15 @@
+---
+to: app/hello.js
+---
+const hello = ```
+Hello!
+This is your first hygen template.
+
+Learn what it can do here:
+
+https://github.com/jondot/hygen
+```
+
+console.log(hello)
+
+
diff --git a/_templates/trails/controller/hello.ejs.t b/_templates/trails/controller/hello.ejs.t
new file mode 100644
index 0000000..095a04e
--- /dev/null
+++ b/_templates/trails/controller/hello.ejs.t
@@ -0,0 +1,15 @@
+---
+to: app/hello.js
+---
+const hello = ```
+Hello!
+This is your first hygen template.
+
+Learn what it can do here:
+
+https://github.com/jondot/hygen
+```
+
+console.log(hello)
+
+
-- 
GitLab