more dev docs
This commit is contained in:
		
							parent
							
								
									9a21716f5e
								
							
						
					
					
						commit
						9147b64625
					
				| @ -1,33 +1,6 @@ | |||||||
| <?php declare(strict_types=1); | <?php declare(strict_types=1); | ||||||
| require_once "core/event.php"; | require_once "core/event.php"; | ||||||
| 
 | 
 | ||||||
| /** |  | ||||||
|  * \page themes Themes |  | ||||||
|  * |  | ||||||
|  * Each extension has a theme with a specific name -- eg. the extension Setup |  | ||||||
|  * which is stored in ext/setup/main.php will have a theme called SetupTheme |  | ||||||
|  * stored in ext/setup/theme.php. If you want to customise it, create a class |  | ||||||
|  * in the file themes/mytheme/setup.theme.php called CustomSetupTheme which |  | ||||||
|  * extends SetupTheme and overrides some of its methods. |  | ||||||
|  * |  | ||||||
|  * Generally an extension should only deal with processing data; whenever it |  | ||||||
|  * wants to display something, it should pass the data to be displayed to the |  | ||||||
|  * theme object, and the theme will add the data into the global $page |  | ||||||
|  * structure. |  | ||||||
|  * |  | ||||||
|  * A page should make sure that all the data it outputs is free from dangerous |  | ||||||
|  * data by using html_escape(), url_escape(), or int_escape() as appropriate. |  | ||||||
|  * |  | ||||||
|  * Because some HTML can be placed anywhere according to the theme, coming up |  | ||||||
|  * with the correct way to link to a page can be hard -- thus we have the |  | ||||||
|  * make_link() function, which will take a path like "post/list" and turn it |  | ||||||
|  * into a full and correct link, eg /myboard/post/list, /foo/index.php?q=post/list, |  | ||||||
|  * etc depending on how things are set up. This should always be used to link |  | ||||||
|  * to pages rather than hardcoding a path. |  | ||||||
|  * |  | ||||||
|  * Various other common functions are available as part of the Themelet class. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| abstract class PageMode | abstract class PageMode | ||||||
| { | { | ||||||
|     const REDIRECT = 'redirect'; |     const REDIRECT = 'redirect'; | ||||||
|  | |||||||
| @ -1,73 +1,4 @@ | |||||||
| <?php declare(strict_types=1); | <?php declare(strict_types=1); | ||||||
| /** |  | ||||||
|  * \page eande Events and Extensions |  | ||||||
|  * |  | ||||||
|  * An event is a little blob of data saying "something happened", possibly |  | ||||||
|  * "something happened, here's the specific data". Events are sent with the |  | ||||||
|  * send_event() function. Since events can store data, they can be used to |  | ||||||
|  * return data to the extension which sent them, for example: |  | ||||||
|  * |  | ||||||
|  * \code |  | ||||||
|  * $tfe = send_event(new TextFormattingEvent($original_text)); |  | ||||||
|  * $formatted_text = $tfe->formatted; |  | ||||||
|  * \endcode |  | ||||||
|  * |  | ||||||
|  * An extension is something which is capable of reacting to events. |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * \page hello The Hello World Extension |  | ||||||
|  * |  | ||||||
|  * \code |  | ||||||
|  * // ext/hello/main.php
 |  | ||||||
|  * public class HelloEvent extends Event { |  | ||||||
|  *     public function __construct($username) { |  | ||||||
|  *         $this->username = $username; |  | ||||||
|  *     } |  | ||||||
|  * } |  | ||||||
|  * |  | ||||||
|  * public class Hello extends Extension { |  | ||||||
|  *     public function onPageRequest(PageRequestEvent $event) {   // Every time a page request is sent
 |  | ||||||
|  *         global $user;                                          // Look at the global "currently logged in user" object
 |  | ||||||
|  *         send_event(new HelloEvent($user->name));               // Broadcast a signal saying hello to that user
 |  | ||||||
|  *     } |  | ||||||
|  *     public function onHello(HelloEvent $event) {               // When the "Hello" signal is recieved
 |  | ||||||
|  *         $this->theme->display_hello($event->username);         // Display a message on the web page
 |  | ||||||
|  *     } |  | ||||||
|  * } |  | ||||||
|  * |  | ||||||
|  * // ext/hello/theme.php
 |  | ||||||
|  * public class HelloTheme extends Themelet { |  | ||||||
|  *     public function display_hello($username) { |  | ||||||
|  *         global $page; |  | ||||||
|  *         $h_user = html_escape($username);                     // Escape the data before adding it to the page
 |  | ||||||
|  *         $block = new Block("Hello!", "Hello there $h_user");  // HTML-safe variables start with "h_"
 |  | ||||||
|  *         $page->add_block($block);                             // Add the block to the page
 |  | ||||||
|  *     } |  | ||||||
|  * } |  | ||||||
|  * |  | ||||||
|  * // ext/hello/test.php
 |  | ||||||
|  * public class HelloTest extends SCorePHPUnitTestCase { |  | ||||||
|  *     public function testHello() { |  | ||||||
|  *         $this->get_page("post/list");                   // View a page, any page
 |  | ||||||
|  *         $this->assert_text("Hello there");              // Check that the specified text is in that page
 |  | ||||||
|  *     } |  | ||||||
|  * } |  | ||||||
|  * |  | ||||||
|  * // themes/mytheme/hello.theme.php
 |  | ||||||
|  * public class CustomHelloTheme extends HelloTheme {     // CustomHelloTheme overrides HelloTheme
 |  | ||||||
|  *     public function display_hello($username) {         // the display_hello() function is customised
 |  | ||||||
|  *         global $page; |  | ||||||
|  *         $h_user = html_escape($username); |  | ||||||
|  *         $page->add_block(new Block( |  | ||||||
|  *             "Hello!", |  | ||||||
|  *             "Hello there $h_user, look at my snazzy custom theme!" |  | ||||||
|  *         ); |  | ||||||
|  *     } |  | ||||||
|  * } |  | ||||||
|  * \endcode |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * Class Extension |  * Class Extension | ||||||
|  * |  * | ||||||
|  | |||||||
							
								
								
									
										119
									
								
								docs/DEV.md
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								docs/DEV.md
									
									
									
									
									
								
							| @ -1,5 +1,121 @@ | |||||||
| # Development Info | # Development Info | ||||||
| 
 | 
 | ||||||
|  | ## Themes | ||||||
|  | 
 | ||||||
|  | Theme customisation is done by creating files in `themes/<theme name>`. | ||||||
|  | 
 | ||||||
|  | The general idea with Shimmie theming is that each `Extension` will add a | ||||||
|  | set of `Block`s to the `Page`, then the `Page` is in charge of deciding | ||||||
|  | how they should be laid out, what they should look like, etc. | ||||||
|  | 
 | ||||||
|  | The overall layout is controlled by `page.class.php`, where the `render()` | ||||||
|  | function will take a look at all of the separate `Block`s and turn them | ||||||
|  | into the final rendered HTML. | ||||||
|  | 
 | ||||||
|  | Individual `Extension`s will render their content by calling functions | ||||||
|  | in `ext/<extension name>/theme.php` - for example the code in | ||||||
|  | `ext/comment/main.php` will display a list of comments by calling | ||||||
|  | `display_comment_list()` from `ext/comment/theme.php`. | ||||||
|  | 
 | ||||||
|  | If a theme wants to customise how the comment list is rendered, it would | ||||||
|  | do so by creating an override file in `themes/<theme name>/comment.theme.php` | ||||||
|  | with contents like: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | class CustomCommentTheme extends CommentTheme { | ||||||
|  |     public function display_comment_list( | ||||||
|  | 		array $images, | ||||||
|  | 		int $page_number, | ||||||
|  | 		int $total_pages, | ||||||
|  | 		bool $can_post | ||||||
|  | 	) { | ||||||
|  | 	    [... render the comment list however you like here ...] | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Events and Extensions | ||||||
|  | 
 | ||||||
|  | An event is a little blob of data saying "something happened", possibly | ||||||
|  | "something happened, here's the specific data". Events are sent with the | ||||||
|  | `send_event()` function. Since events can store data, they can be used to | ||||||
|  | return data to the extension which sent them, for example: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | $tfe = send_event(new TextFormattingEvent($original_text)); | ||||||
|  | $formatted_text = $tfe->formatted; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An extension is something which is capable of reacting to events. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### Useful Variables | ||||||
|  | 
 | ||||||
|  | There are a few global variables which are pretty essential to most extensions: | ||||||
|  | 
 | ||||||
|  | * $config -- some variety of Config subclass | ||||||
|  | * $database -- a Database object used to get raw SQL access | ||||||
|  | * $page -- a Page to holds all the loose bits of extension output | ||||||
|  | * $user -- the currently logged in User | ||||||
|  | * $cache -- an optional cache for fast key / value lookups (eg Memcache) | ||||||
|  | 
 | ||||||
|  | Each of these can be imported at the start of a function with eg "global $page, $user;" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### The Hello World Extension | ||||||
|  | 
 | ||||||
|  | Here's a simple extension which listens for `PageRequestEvent`s, and each time | ||||||
|  | it sees one, it sends out a `HelloEvent`. | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | // ext/hello/main.php | ||||||
|  | public class HelloEvent extends Event { | ||||||
|  |     public function __construct($username) { | ||||||
|  |         $this->username = $username; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public class Hello extends Extension { | ||||||
|  |     public function onPageRequest(PageRequestEvent $event) {   // Every time a page request is sent | ||||||
|  |         global $user;                                          // Look at the global "currently logged in user" object | ||||||
|  |         send_event(new HelloEvent($user->name));               // Broadcast a signal saying hello to that user | ||||||
|  |     } | ||||||
|  |     public function onHello(HelloEvent $event) {               // When the "Hello" signal is recieved | ||||||
|  |         $this->theme->display_hello($event->username);         // Display a message on the web page | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | // ext/hello/theme.php | ||||||
|  | public class HelloTheme extends Themelet { | ||||||
|  |     public function display_hello($username) { | ||||||
|  |         global $page; | ||||||
|  |         $h_user = html_escape($username);                     // Escape the data before adding it to the page | ||||||
|  |         $block = new Block("Hello!", "Hello there $h_user");  // HTML-safe variables start with "h_" | ||||||
|  |         $page->add_block($block);                             // Add the block to the page | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | // themes/mytheme/hello.theme.php | ||||||
|  | public class CustomHelloTheme extends HelloTheme {     // CustomHelloTheme overrides HelloTheme | ||||||
|  |     public function display_hello($username) {         // the display_hello() function is customised | ||||||
|  |         global $page; | ||||||
|  |         $h_user = html_escape($username); | ||||||
|  |         $page->add_block(new Block( | ||||||
|  |             "Hello!", | ||||||
|  |             "Hello there $h_user, look at my snazzy custom theme!" | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Cookies | ||||||
|  | 
 | ||||||
| ui-\* cookies are for the client-side scripts only; in some configurations | ui-\* cookies are for the client-side scripts only; in some configurations | ||||||
| (eg with varnish cache) they will be stripped before they reach the server | (eg with varnish cache) they will be stripped before they reach the server | ||||||
| 
 | 
 | ||||||
| @ -16,5 +132,8 @@ themes, be careful with these, and avoid styling them, eg: | |||||||
| - shm-clink = a link to a comment, flash the target element when clicked | - shm-clink = a link to a comment, flash the target element when clicked | ||||||
|   * data-clink-sel |   * data-clink-sel | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | ## Fin | ||||||
|  | 
 | ||||||
| Please tell me if those docs are lacking in any way, so that they can be | Please tell me if those docs are lacking in any way, so that they can be | ||||||
| improved for the next person who uses them | improved for the next person who uses them | ||||||
|  | |||||||
							
								
								
									
										44
									
								
								index.php
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								index.php
									
									
									
									
									
								
							| @ -1,48 +1,4 @@ | |||||||
| <?php | <?php | ||||||
| /** |  | ||||||
|  * \mainpage Shimmie2 / SCore Documentation |  | ||||||
|  * |  | ||||||
|  * SCore is a framework designed for writing flexible, extendable applications. |  | ||||||
|  * Whereas most PHP apps are built monolithically, score's event-based nature |  | ||||||
|  * allows parts to be mixed and matched. For instance, the most famous |  | ||||||
|  * collection of score extensions is the Shimmie image board, which includes |  | ||||||
|  * user management, a wiki, a private messaging system, etc. But one could |  | ||||||
|  * easily remove the image board bits and simply have a wiki with users and |  | ||||||
|  * PMs; or one could replace it with a blog module; or one could have a blog |  | ||||||
|  * which links to images on an image board, with no wiki or messaging, and so |  | ||||||
|  * on and so on... |  | ||||||
|  * |  | ||||||
|  * Dijkstra will kill me for personifying my architecture, but I can't think |  | ||||||
|  * of a better way without going into all the little details. |  | ||||||
|  * There are a bunch of Extension subclasses, they talk to each other by sending |  | ||||||
|  * and receiving  Event subclasses. The primary driver for each conversation is the |  | ||||||
|  * initial PageRequestEvent. If an Extension wants to display something to the |  | ||||||
|  * user, it adds a block to the Page data store. Once the conversation is over, the Page is passed to the |  | ||||||
|  * current theme's Layout class which will tidy up the data and present it to |  | ||||||
|  * the user. To see this in a more practical sense, see \ref hello. |  | ||||||
|  * |  | ||||||
|  * To learn more about the architecture: |  | ||||||
|  * |  | ||||||
|  * \li \ref eande |  | ||||||
|  * \li \ref themes |  | ||||||
|  * |  | ||||||
|  * To learn more about practical development: |  | ||||||
|  * |  | ||||||
|  * \li \ref scglobals |  | ||||||
|  * \li \ref unittests |  | ||||||
|  * |  | ||||||
|  * \page scglobals SCore Globals |  | ||||||
|  * |  | ||||||
|  * There are four global variables which are pretty essential to most extensions: |  | ||||||
|  * |  | ||||||
|  * \li $config -- some variety of Config subclass |  | ||||||
|  * \li $database -- a Database object used to get raw SQL access |  | ||||||
|  * \li $page -- a Page to holds all the loose bits of extension output |  | ||||||
|  * \li $user -- the currently logged in User |  | ||||||
|  * |  | ||||||
|  * Each of these can be imported at the start of a function with eg "global $page, $user;" |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ | ||||||
| * Make sure that shimmie is correctly installed                             * | * Make sure that shimmie is correctly installed                             * | ||||||
| \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user