Skip to content
This repository has been archived by the owner on Jan 25, 2021. It is now read-only.

Extension System Discussion #90

Open
johnforte opened this issue May 16, 2016 · 5 comments
Open

Extension System Discussion #90

johnforte opened this issue May 16, 2016 · 5 comments

Comments

@johnforte
Copy link
Contributor

Every good forum software needs to have a plugin system. I am very partial to the event's dispatch type system with new folder theme overriding the default.

What is everyone's favorite way to create a plugin system?

@brunnopleffken
Copy link
Owner

I've been thinking about it for several months, trying to get a solution for a plugin system. I began to scratch something in past December, but I put it aside for a while until I get an efficient solution. Instead "plugins" I called it "extensions", but it's the same idea.

  • All extensions will be inside the /extensions folder in the project root. It has the following format: /extensions/[vendor]/[name], for example: /extensions/JohnForte/DoSomethingAwesome. This directory will contain all assets, views and controller (like a mini-application, inspired by Ruby and NPM packages).
  • There will be a table containing all registered extensions and an option to enable or disable it (just as WordPress does).

I like the way CakePHP handles extensions (http://book.cakephp.org/3.0/en/plugins.html), but this solution - of course - involves modifying the controllers manually, as it's a framework. In our case all has to be done automatically.

As you can see, the PHP side of it is relatively easy to implement: I just load the controller and run it, it'll be accessed just like the default controllers are. New pages will be accessed the same way the others inside /templates/default are. The hard part is HOW TO MODIFY EXISTING VIEWS? I'm thinking to use JavaScript, so any extension can add a link, a button, a modal window, using JS (element.innerHTML or $(element).html()) but I haven't made any test. The idea is not override the default template, but add elements to it dynamically (that's why JS sounds nice), as you can have multiple extensions running at the same time.

Any thoughts?

@johnforte johnforte changed the title Plugin System Discussion Extension System Discussion May 17, 2016
@johnforte
Copy link
Contributor Author

johnforte commented May 17, 2016

I can get behind the php part, as you pointed out it is pretty standard at this point in php development.

As for the view, I don't like the javascript way of doing things. I think using javascript can cause a lag if someone is on a slow computer or internet connection. This would cause a lot of flickering, but I be curious to check it out if you put together a demo.

I been thinking about this for an 1 hour and really haven't come to my own conclusion of how I would do it.

@brunnopleffken
Copy link
Owner

brunnopleffken commented May 17, 2016

I've been thinking about it today... JS is a two-bladed sword: although it's an easy and non-intrusive method to add elements to the default templates without messing up everything, it may flicker the screen and depends a lot of client-side processing.

The other way is to add a tag (let's suppose an HTML comment like <!-- EXTENSION=VendorName.ExtensionName.SomeHTMLBlock -->) and this will be replaced using RegEx to whatever I want from server-side. This is an also easy solution to add a piece of HTML code into a template. But I see two cons using it: a) every template file will run through a middleware that parses the HTML code looking for those tags, but I need to measure the impact on page load time; b) overwriting the template files - due to a software update e.g. - you'll... well... loose everything.

@johnforte
Copy link
Contributor Author

I wouldn't worry about the middleware part since we can just build all HTML to be cached in the database, so it would be generated once.

I was thinking about maybe using json to plot out how the page looks? So it could look like...

{
 "html":{
      "head":{
          "script":"js/jquery.min.js"
      },
      "body":{

      }
   }
}

Then all users would have to do is override the sections that matter to them? I am taking this straight from how magento 1.x does it with xml. Thoughts?

@R-J
Copy link

R-J commented Feb 5, 2017

I would suggest modulizing the templates as much as possible. Instead of using
/templates/default/Thread.Add.phtml
/templates/default/Thread.Edit.phtml
/templates/default/Thread.Index.phtml
...

you can use
/templates/default/Thread/Index.phtml
/templates/default/Thread/Index/Poll.phtml
/templates/default/Thread/Index/AnsweredPoll.phtml
/templates/default/Thread/Index/PollOptions.phtml
/templates/default/Thread/Index/Replies.phtml
/templates/default/Thread/Index/RepliesDesktop.phtml
/templates/default/Thread/Index/RepliesMobile.phtml
/templates/default/Thread/Index/RepliesQuote.phtml
...

I don't know your code, but I simply start from the html comments in Thread.Index.phtml to explain what I mean. This is the (incomplete, I know) "structure":

	Line 49: 		<!-- START poll -->
	Line 53: 				<!-- START answered poll -->
	Line 70: 				<!-- END answered poll -->
	Line 72: 				<!-- START poll options -->
	Line 95: 				<!-- END poll options -->
	Line 98: 		<!-- END poll -->
	Line 123: <!-- BUTTONS -->
	Line 140: <!-- REPLIES -->
	Line 155: 						<!-- START tablet/desktop only -->
	Line 160: 						<!-- END tablet/desktop only -->
	Line 161: 						<!-- START mobile only -->
	Line 165: 						<!-- END mobile only -->
	Line 186: 						<!-- START quote -->
	Line 195: 						<!-- END quote -->
	Line 245: <!-- PAGINATION AND BUTTONS -->
	Line 260: <!-- MODERATION -->
	Line 293: <!-- RELATED THREADS -->
	Line 311: <!-- DELETE POST LIGHTBOX -->

In order to build the poll you would have a /templates/default/Thread/Index/Poll.phtml that looks like this

minimal markup
include /templates/default/Thread/Index/AnsweredPoll.phtml
minimal markup
include /templates/default/Thread/Index/PollOptions.phtml
minimal markup

This has the following advantages:

DRY: you would be able to create blocks which are usable not only at one place but anywhere. If they afford a different look, that can be done with CSS.

Theme-able: instead of simply including the file, you could write a getTemplate() function. Whenever a new extension or theme is registered, it must provide which templates are overwritten. getTemplate() can search for the required template in the array of registered overrides and serve the replaced template or the original one. Another approach would be to compile templates (by concatenating them to a file like you have by now) and to simply recreate the compiled templates when an extension wants to override a template.

To my understanding that is how templating libraries do it. Although I think in general they are not needed, they make it easier for people to write themes and they help you if you have complex layouts.

@brunnopleffken brunnopleffken mentioned this issue Apr 12, 2017
8 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants