Jump to content

Harmster

Members
  • Posts

    137
  • Joined

  • Last visited

Everything posted by Harmster

  1. Introduction Dear community. As some of you may know I've been busy creating a MVC Module for Processwire. I've finished quite a bit of it and I am now ready for a tutorial on a quick website to get you started! For this tutorial I am using a clean install of Processwire 2.3 and my Module 0.2.4 Get the module at Github http://github.com/hawiak/mvcmodule . Main focus of the module is to split logic from design without losing the flexibility of Processwire we all fell in love with. Alright lets get started. Installation Once you have the module downloaded we are going to install it, we need the MvcModule folder in the /site/modules folder. And we need the AppController in the /site/templates folder (You can find the AppController in the /site/templates folder) Once you've put the folder in there we are going to install the module, check for new modules and you'll see MvcModule Click on it and hit install to install the module. Once you've installed the module you'll see some configure settings and you'll notice a new tab on your admin. But click submit, dont forget this or all the paths WONT WORK! Setting up your home controller Ok we are ready to set up our first controller. To easily set up your template to enable MVC we are going to the MVC tab in your navbar. You'll notice a button saying " Create controller" Click on "Create controller" and for this tutorial we are going to use the home template, select the home and click "Create". If everything is correct you will see this: Now we are done in the process side of it and we'll get into the coding. Get your favourite code editor open and lets create our controller. Open the /site/templates/home.php file in your editor. Remove the code thats in there completely. And save it. For the module to work with the template file we need to create a class called HomeController and extend AppController. like so: <?php class HomeController extends AppController{ } Creating Views and layouts If you go to your websites homepage you'll see something along the lines of: Thats because by default you will need an Index method, a home method for your controller, so lets create one! <?php class HomeController extends AppController{ public function index(){ } } Lets try it again! Oops... Well it seems like we're missing a view, so lets create the view, we first need to create a folder with called Home (the same as the controller name but start with capital) And in that folder we'll create a file called index.tmpl Now of you run it you'll see that you are not quite done yet you'll see something like this: I promise after we create the layout we are done. So lets create a folder called layouts and a file called layout.php in there. Displaying data Now we're done with the setup and we can start coding, lets say you want to get the content fromt he field body on your page displayed? Well thats easy put this in your index method. $this->set('body', $this->page->body); What this does is that it sets a variable in the view we can use called body so all we need to do to display this is go to our view. And add {{body}} to the view. Now go and refresh your page! oh wait... nothing shows up...? Oh yes we use Twig template engine we need to add this to our layout.php {% block view %} {% endblock %} (Yes yes I know its complicated for just a simple task but trust me you'll love it later!) Refresh your page and check it out! You'll see that the text is displaying but the markup isn't really working, we need to use the |raw extension in order to make this work, so change the index.tmpl content to this {{ body|raw }} Use |raw for all the HTML markup, always. Styles, scripts and snippets Now this is quite boring, I know but lets start doing some interesting stuff, lets implement Bootstrap! go and download bootstrap at getbootstrap.com Once you've downloaded create a folder in /site/templates called "assets" the dist copy the bootstrap.min.css out of /dist/css to /site/templates/assets/styles and /dist/js/bootstrap.min.js to /site/templates/assets/scripts/ Now we want to use this, MvcModule has some great options for this! Change your HomeController to this <?php class HomeController extends AppController{ public $scripts = array( '1' => 'bootstrap.min.js'); public $styles = array( '1' => 'bootstrap.min.css'); public function index(){ $this->set('body', $this->page->body); } } Now go over to your layout and change the contents of your layout to this: <head> {{ this.render_headers()|raw }} </head> {% block view %} {% endblock %} You'll now see your style (If not try going to the MvcModule configure settings and remove the first / from /site/templates/assets) Now we forgot to include JQuery, so lets download jquery at jquery.com We need to put that in the /site/templates/assets/scripts And we need to put it in the array, you can just do that as follow: public $scripts = array( '2' => 'bootstrap.min.js', '1' => 'jquery.min.js'); The number in this array indecates the order on which the scripts will be loaded. Now you should see something like this! Now lets create a navbar with all the pages using the bootstrap navbar component. To do this we will create a snippet create a folder called snippets in /site/templates and a file called navbar.php Lets first create a variable with all the pages in the index method $this->set('menu', $this->pages->find('/')); Lets now create our snippet, lets just create this first in our snippet navbar.php <nav class="navbar navbar-default" role="navigation"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link</a></li> </ul> </div> </nav> We need to tell the controller to use this snippet we do that by using an array. Change your controller to the following: <?php class HomeController extends AppController{ public $scripts = array( '2' => 'bootstrap.min.js', '1' => 'jquery.min.js'); public $styles = array( '1' => 'bootstrap.min.css'); public $snippets = array( 'navbar' => 'navbar.php'); public function index(){ $this->set('body', $this->page->body); $this->set('menu', $this->pages->find('/')); } } And change your layout to this: <head> {{ this.render_headers()|raw }} </head> {% block navbar %} {% endblock %} {% block view %} {% endblock %} You see that I created a block here and called in Navbar. The snippets content (that we assigned to navbar => file_name) will be put in this block! So lets now use our variables and the Twig template engine to the fullest! Change the navbar.php snippet to: <nav class="navbar navbar-default" role="navigation"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> {% for item in menu %} <li class=""><a href="{{ item.url }}">{{ item.title }}</a></li> {% endfor %} </ul> </div> </nav> You see we use a for loop here and use the PageArray menu here and generate the menu here. You can use the variables in the view as well. Setting a title Lets set a title, this is fairly easy, lets define a variable in our controller that will be the same for every view in this controller public $title = "Home controller"; Now go to your layout.php and do add this to the head: <title>{%block title %}{% endblock %} {{ this.controller.title }}</title> Now as you can see we created a block, what this allows us to do is create the same block in the view like this: {% block title %}Index{% endblock %} And you will see that your title is "Index Home controller". This is because the title block replaced the title block in the layout file. Views Inside views you still have access to processwire objects and even to the MvcModule as you've seen with render_headers(). The view template used is Twig, check out more here http://twig.sensiolabs.org/doc/templates.html This is a basic setup for a website with MvcModule. I will extend this tutorial and update it whenever needed!
  2. Ok that sounds fair, however I have no idea what values I should put there?
  3. Hey, I am trying to create a template with a field with the type page from a module using the API. This is some of the code I use to generate the field and the template. The field $mvc_register_field = $this->fields->get('mvc_register_page_id'); if(!$mvc_register_field->id){ $mvc_register_field = new Field(); $mvc_register_field->name = 'mvc_register_page_id'; $mvc_register_field->label = 'MVC Register Page ID'; $mvc_register_field->description = 'Checkbox that enables MVC for a page'; $mvc_register_field->type = 'FieldtypePage'; $mvc_register_field->save(); } And the template if(!$this->templates->mvc_register){ $t = new Template(); $t->name = 'mvc_register'; $fieldgroup = $this->fieldgroups->get($t->name); if(!$fieldgroup->id){ $fieldgroup = new Fieldgroup(); $fieldgroup->name = $t->name; $fieldgroup->add($this->fields->get('mvc_register_page_id')); $fieldgroup->save(); } $t->fieldgroup = $fieldgroup; $t->roles = array($this->roles->get('superuser')->id); $t->save(); } And this is how i try to create a page $controller_registry = new Page(); $controller_registry->template = $this->templates->get('mvc_register'); $controller_registry->parent = $this->pages->get("name=" . self::PAGE_NAME); $controller_registry->title = $controller_name; $controller_registry->name = $controller_name; $controller_registry->mvc_register_page_id = $this->pages->get('url=page_url'); $controller_registry->save(); Which gives me this error: How do I resolve this?
  4. Hey, thanks! that is helpful, I am almost certain that your module is about 20 times better then mine, but I do like to try and make my own just to see if I can. Thanks for sharing! I'll implement this.
  5. Edit: I was toofast, try to use the $config->url or $config->path properties. (Check cheatsheet.processwire.com for more details. )
  6. Twig has been added as template engine
  7. Updating the guide, rewrote the whole module. Still not reliable but I need some testing from other people too. Wrote the install instructions and will update this over the week.
  8. Any idea how I can check this? I used posix_getpwuid(posix_geteuid()); and it showed hawiaknl
  9. Page or Template? Because you say subpage, but if it isnt a child page the word subpage is confusing, How did you set up the Courses? as fields? as text? or as a child page?
  10. Hey there, I am creating my GUI for my MVC PW Module. And I like to create a directory and a php file in the /site/templates folder. I am using php as the hawiaknl and the owner of the /site/templates folder is hawiaknl But i get permission denied every time I tried 755, 777 but that shouldnt matter caus I am the owner right? Maybe I am just htinking wrong, could someone help me out? (the script is executed from /site/modules/MvcModule/MvcModule.module) Like so <?php $h = fopen($path.$template->name.'.php', 'w') or die("Cannot generate controller file" . $path.$template->name); ?>
  11. I haven't had an answer yet so I figured I post some more details. I want a setting that enables MVC for my Module on template level, i want this to be a checkbox. How do I approach this? Can this be done with code lets say in the ___install() method of my module? Much appriciated
  12. Created new OP. EDIT: No i was not aware, however, I do like to try around a little and I managed to rebuild part of my site within 30 minutes to the MVC model I just made, there are some bugs and its far from polished but its 2 days old...
  13. Hey, I am looking for a good way to add a setting to a template using code only. Like a checkbox in the template options... Thanks
  14. WORK IN PROGRESS PLEASE BE AWARE Processwire MVC by Harmster A quick guide Introduction I am developing a MVC like module for Processwire. My goal is to split code login and design as much as possible. If you're familiar with CakePHP and or Zend you shouldn't have much trouble as those are the frameworks I loosely based this on. This module comes with Twig Template engine from Symfony 2 (see more here) Download Download PWMvc at github: https://github.com/Hawiak/MvcModule Configure 1) Drag/upload/add the /site/modules/MvcModule folder into your project's module folder. 2) Search for new Modules 3) Install MVC 4) Press "Submit", this is important, without the submit your paths are not saved. 5) Leave every textfield as it is for now, these are the defaults. 6) Create 3 folders in your /site/templates folder and call them assets, snippets and layouts 7) You are going to need a default layout file, just create a new php file in the folder layouts you just created called layout.php 8) Place the AppController.class in your /site/templates 9) Place the _create_mvc.php in your /site/templates 10) Edit your /site/config.php and add the following line $config->appendTemplateFile = '_create_mvc.php'; Files, Folders and Fields You might be wondering what you just installed. Here's a quickreference guide to the files: FILE: AppController.class This is actually just an empty class and it can be used for things that are all the same over your website, so not controller reliable. For example a title that you want to append on each one of the controllers, or scripts or stylesheets you want to have all over your website. FILE: _create_mvc.php This script sets up the MVC, it fetches the action, calls the methods. This script runs after EVERY template but only works if the template has an MVC field. FIELD: mvc If you've installed the MVC module you will notice you have an extra field installed called MVC. Add this field to every template you want to enable MVC on. FOLDER: assets In this folder there will be 2 folders called, scripts and styles by default but you can place any folders in here. By default MVC will look in these folders for scripts or styles you use using the $script or $styles property of the controller. FOLDER: layouts In this folder you will put your layout files, layout files is the structure of your website, think about a <head> and <body> tag, in general this is the same for most of your views, however you can set layouts per controller, even per action. Read about that later. FOLDER: snippets In this folder you will put your snippet files, snippets are piece of code that you re-use. The Controller The Controller is the Base provided by MvcModule. It has basic functionality and some properties (These will be extended if needed over time) For now the Controller class has these properties: layout - The "layout" property is used to set a file to be used as a layout file, this can be done in the method or the controller. view - The "view" property can be used to change the view for the action, by default the view will be the same as the action e.g. index.view for the index action and edit.view for the edit action. vars = array() - An array with all the variables that are being used in the controller and in the view, try and not use this variable but it is accesible in any controller or the AppController. Use the set() method instead. render_layout = 1 - This will be a switch to turn of the layout rendering, handy for ajax calls. layout_vars = array() - This is a array with all the vars being used in the layout, same applies here as for the vars, try and not use this variable but still it is accesible throughout your project. Use the set_layout_var instead. scripts = array() - An array with all the scripts for a project, use as follow: $scripts = array('1' => 'jquery.js'); The 1 is the sequence of which the scripts will be loaded, it is handy when you want to load jquery before you load foundation or bootstrap. The scripts need to be in the /site/templates/assets/scripts folder by default. styles = array() - An array with all the styles for a project, use as follow: $styles= array('1' => 'jquery.css'); The 1 is the sequence of which the styles will be loaded, it is handy when you want to bootstrap first before your theme The styles need to be in the /site/templates/assets/styles folder by default. And these methods: set($var, $val) - Will set a variable for your View set_layout_var($var, $val) - Will set a variable for your Layout The AppController The AppController is the class you want to extend when creating a controller, its basicly an empty class where you can put custom stuff in, this class extends the Controller inside the MvcModule folder. Make custimizations in this class to prevent issues while updating MvcModule. Setting up a controller To set up a controller you need to create a file in the root of the template folder (/site/template). Name it like you named the template. It needs to be the same name as the template. Then create a class in it with a capital at the beginning, and append it with the word Controller. This is an example for the Controller Test in /site/template/test.php: <?php class TestController extends AppController{ } ?> You'll then have to set up methods inside this class, lets say you have an edit, view, delete and a list view of a few pages. <?php class TestController extends AppController{ public $title; public function index(){ $this->set('list-view', $pages->find('/')); } public function view(){ $this->set('view', $pages->get($this->input->urlSegments[2])); } public function edit(){ $this->set('edit', $pages->get($this->input->urlSegments[2])); } public function delete(){ $page_id = $sanitizer->value($this->input->urlSegments[2]); $this->pages->get($page_id)->delete(); } } ?> The code here is just to demonstrate how different views work and far from efficiant. In order for the views to work you'll have to create views in the view folder, like index.view, view.view, edit.view and delete.view. Because the TestController extends AppController and AppController extends Controller and Controller extends Wire you can use ProcessWire function by using $this. Template variables The following variables should be available in your template/layout/snippet (Not all of them have been properly tested) user pages page sanitizer files input permissions roles templates session config controller wire this (mvc module) Using Layouts A layout is the markup of your website. Its most of the time the same on all the pages for every view. It goes like. A very simple example of a working layout is: <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> {{ this.render_headers()|raw }} <title>{{ this.controller.title }}</title> </head> <body data-spy="scroll" data-target="#main-nav"> {{ this.render_snippet('navbar.php')|raw }} {{ this.render_view()|raw }} {{ this.render_snippet('login.php')|raw }} </body> </html> As you can see I used $this->controller->title you can set any variable you like and used it in here. Also, there is the $this->view_body. The view body is the result from the rendered view. And I use the method $this->render_headers() this renders the script and styles for your layout defined in your controller. You can define a layout for each controller or even for each method. Using $this->layout = 'yourlayout.php'; anywhere in your controller. Using Snippets A snippet can be used for a lot of stuff, like your navbar or your login, something you want to re use but not necessary on your layout. You can render a snippet using the {{ render_snippet(string $snippet_name, array $vars)|raw }} Just give the name e.g. login.php and an array of variables you want to use within the snippet, the variables are optional. The snippets can also access controller variables and/or wire variables objects. Using Views A view is where you will put your markup and all the stuff that your visitor will see. A simple basic page could just display a body A view that just displays the body that is set in the controller ($this->set('body', $this->pages->get('/'))) and then just echo $body on the view This is an example view: <div> {{ body }} </div> UPDATE Twig template engine has been implemented see the Twig documentation for more info TODO: Create more controller methods that make it easier to generate views Create an Error class for MVC enabled templates. Implementing Twig as a template engine for views and possible layouts, snippets. Implement feutures like extend in twig. May change the core. Advanced testing Write tutorial The module now features an admin panel. Create view files/folders from admin panel Create controllers from the admin panel Create new methods in the controller from the admin panel Changelog - 11/20/2013 - Updated whole module - 11/22/2013 - Implemented Twig, renamed views extension to .tmpl WORK IN PROGRESS PLEASE BE AWARE
  15. Yeah, that shouldn't matter, the token is there to prevent others from sending their forms to your backend. Having 2 the same tokens is OK. The tokens aren't there to indentify your form. Source: http://stackoverflow.com/questions/14715250/generating-csrf-tokens-for-multiple-forms-on-a-single-page
  16. Hey, I've made a gallery and it all works fine, all the images are in an image inputfield and when I upload a bunch it puts the images in the order the pictures are uploaded. How can I sort the pictures on the title? The titles are like following mih_5500-1200.jpg and mig_5555-1200.jpg etc etc I display the pictures with <?php foreach($page->images as $image){ //blabla } ?>
  17. Hey ryan, I love this profile, great for just creating a tool real quick. However, when I started a new project for a coworker of mine and installed a fresh install of PW + this profile I encountered this error: Notice: Undefined variable: onlyViewable in /home/macleod/public_html/staging/wire/core/Page.php on line 807 And it looks like:
  18. The thing is that even with this code the template file will still be apended and you'll get the complete html page with <head> <body> etc and I don't need that, I want just 1 html string or a json string without the template files. Sorry if I wasn't clear.
  19. Hey, I am using the Foundation 4 Site Template that Ryan made and I am currently working on a template that is going to be called via ajax and I'd like to just generate the content of the template itself instead of the all the appended/prepended content that the config adds. How do I "reset" the config properties for just 1 template to the default setting? Thanks in advance.
  20. The purpose for this is basicly to check if a user that is logged in is friended with one of the fellow players listed in match->fellow_players A fellow player summoner_id might not exist in the user templates at all. A friend is saved in the friend template user_1 and user_2 being either the logged in user or the friended user. I hope this clearified anything... Its hard to explain
  21. Hey, I am trying to make a selector to check something on my website (A social site) So i want to check if there's a friend relation between 2 users. but here's the thing: I've got a user template that has the following fields (and some more): -summoner_id (text) -summoner_name (text) And i've got a match template having a repeater field called fellow_players this fellow players has a summoner_id field aswell so: -summoner_id (text) Now i've got a friend template with a few fields including -user1 (page to user template) -user2 (page to user template) Now what i want is to check if there's a friend template with user1->summoner_id OR user2->summoner_id == fellow_player->summoner_id Is this doable with a selector or do i need to use more php?
  22. Yup turned out, that was the answer. Super thanks!
  23. Hey, I got this error today and I dont even know what it means: I get this error because of this selector: $items = $pages->find("template=match|notification, summoner_id=$summoner_string, sort=-create_date, limit=15"); (The summoner_string contains IN THIS CASE: |24604493|27565345|22443070|442232|20293661|36868417|19315465|30962047|37560273|27475320|27565345 ) Now what happens is when I log into a user that has this $summoner_string:27565345|27475320 it does not happen... Though, this user isnt retrieving notification templates. Both templates contain the create_date and summoner_id fields Please help?
  24. Hey, I've made this really simple session module that lets to add messages to the session and render it. Here's the complete php file: <?php class SessionMessage extends Process implements Module, ConfigurableModule { public $messages = array(); public static function getModuleInfo() { return array( 'title' => 'SessionMessage', 'version' => 101, 'summary' => 'An example module used for demonstration purposes. See the /site/modules/Helloworld.module file for details.', 'href' => 'http://www.processwire.com', 'singular' => true, 'autoload' => true, ); } public function init() { $this->setFuel('sessionMessage', $this); } static public function getModuleConfigInputfields(array $data){ $modules = Wire::getFuel('modules'); $fields = new InputfieldWrapper(); $field = $modules->get("InputfieldText"); $field->attr('name+id', 'error_class'); $field->attr('value', $data['error_class']); $field->label = "Error class"; $field->description = 'Enter your error class for error handling.'; $fields->append($field); $field = $modules->get("InputfieldText"); $field->attr('name+id', 'success_class'); $field->attr('value', $data['success_class']); $field->label = "Success class"; $field->description = 'Enter your error class for success handling.'; $fields->append($field); $field = $modules->get("InputfieldText"); $field->attr('name+id', 'alert_class'); $field->attr('value', $data['alert_class']); $field->label = "Alert class"; $field->description = 'Enter your error class for alert handling.'; $fields->append($field); return $fields; } //void public function add($type, $message){ //types could be error, alert or success array_push($this->messages, array($type => $message)); $this->session->set('messages', $this->messages); } public function render($clean=true){ $html = ""; $this->messages = $this->session->get("messages"); foreach($this->messages as $array){ foreach($array as $type => $message){ $class = $type.'_class'; $html .= '<div class="' . $this->$class . '">'; $html .= $message; $html .'</div>'; } } $this->session->messages = $this->messages; if($clean == true){ unset($this->messages); $this->session->set('messages', $this->messages); } return $html; } } Installation: 1) Install the module 2) Give classes to each of the default fields: error success alert Usage: To add a message use: $sessionMessage->add('error', 'This is an error message'); To display all messages: echo $sessionMessage->render(); If you don't want the module to erase the messages after being displayed: echo $sessionMessage->render(false); I am currently using this in combination with Zurb Foundation Hope it helps someone. -Harmster
×
×
  • Create New...