larrybotha Posted May 9, 2014 Author Share Posted May 9, 2014 haha, none taken - we've built quite a specific set of tools, so we don't expect it to be to everyone's liking. Our generator may be a good starting point for a more generic one. Link to comment Share on other sites More sharing options...
gebeer Posted May 9, 2014 Share Posted May 9, 2014 Hi Larry, I have started a new thread about Yeoman genarator for PW. Link to comment Share on other sites More sharing options...
studioweb Posted June 5, 2014 Share Posted June 5, 2014 Hi Larry, Thanks for putting this together and sharing! One question: I've added the following files: - a root page 'tasks', - a template 'tasks', - a controller 'tasks_controller' and the url /tasks/ is responding fine, but I was assuming that the url /tasks/action/update/ could be controlled with the following function in the controller: function page_action(){ if($this->input->urlSegment1=='update' echo 'update function'; } } Or is it still necessary to add the page /tasks/action/ and so on? Link to comment Share on other sites More sharing options...
studioweb Posted June 5, 2014 Share Posted June 5, 2014 Update: I've found my own solution, but please do tell if this is not the best approach In core/controller.php after: $func = 'page_'.f8\Strings::snake_case($this->page->name); if (!method_exists($this, $func)) { $func = 'index'; } add: $func = 'page_'.f8\Strings::snake_case($this->input->urlSegment1); if (!method_exists($this, $func)) { $func = 'index'; } somewhere on the 86th line so the controller looks at the first 'function'-segment Link to comment Share on other sites More sharing options...
larrybotha Posted June 6, 2014 Author Share Posted June 6, 2014 Hi Nico, UrlSegments are something we haven't yet really considered for the framework - purely because we haven't had to use them yet! You were on the right track, but the name of the function wasn't outputting correctly with your modification - call() allows you to define a function based on a particular path. You'd have to loop through all urlSegments, until you get to an empty one, and then append a string of all the segments to the name of the page in call(). In your controller you would then have: // tasks_controller.php ... // handle requests to tasks/action/update function page_tasks_action_update() { return $this->render('some-template', array( 'some_var' => 'some_value' )); } ... I've made an update to core/controller.php: https://github.com/fixate/pw-mvc-boilerplate/blob/master/core/controller.php#L80-L97 to handle urlSegments 1 Link to comment Share on other sites More sharing options...
studioweb Posted June 15, 2014 Share Posted June 15, 2014 Thanks for the update Another thing: I'd like the ability to render a template from the partials-folder (or newly created dialogs-folder) from a controller. This is useful in some cases, eg loading stuff with ajax. Is this possible at the moment or should I edit some things in controller.php and view.php? thx again! Link to comment Share on other sites More sharing options...
studioweb Posted June 15, 2014 Share Posted June 15, 2014 Another thing; what to do when I've to retrieve a ajax dialog with some HTML from a view-template. At this point, the api_controller.php is called but this file doesn't allow $this->render like controller.php does. Link to comment Share on other sites More sharing options...
larrybotha Posted June 15, 2014 Author Share Posted June 15, 2014 You can render templates from wherever you like - by default render() will look inside views/, but you can set a relative path from there: // MyController.php class MyController extends ApplicationController { ... function index() { ... // use views/dialogs/my_template.html.php return $this->render('dialogs/my_template', array(...)); } } will look inside views/dialogs/ Did I understand your question correctly? ---------------------------------------------- WRT api_controller.php, my knowledge of ajax is pretty slim (I didn't write any of the API stuff, so I may be wrong here), but what appears to happen is when a request comes in from your JS, the boilerplate will look at controllers/api/my_controller.php instead of controllers/my_controller.php. Inside controllers/api/my_controller.php you will extend ApiController, instead of Controller. The call() method in the ApiController class, in contrast to the Controller class', looks for a method that matches an HTTP verb you would need to define in your controller (PUT, PATCH, DELETE, and UPDATE don't seem to be supported - perhaps because ProcessWire only supports GET and POST), and handles it accordingly. The ApiController class has its own partial() method to generate markup inside controllers. The return value of your method is then handed back to your JS. So, in a nutshell, you should be able to create a new controller as follows: <?php /** * MyController - API Controller */ class MyController extends ApiController { ... // GET verb specified in AJAX request function get() { ... $html = ''; // use views/partials/dialogs/my_dialog.html.php $html .= $this->partial("dialogs/my_dialog", array(...)); // return results of request to js return array( 'html' => $html ); } } Additionally, there's a function, render_js_data(), in javascript.php which will retrieve the page's path and template as a window object in a script tag for easy access in your javascript. You can simply add it to scripts.html.php: // scripts.html.php ... <?= $this->render_js_data() ?> <?= $this->render_scripts() ?> and in your js then use: // main.js if (this.processWire.template === 'my_template') { // do something } I hope I've made sense! Link to comment Share on other sites More sharing options...
Mackski Posted September 8, 2014 Share Posted September 8, 2014 Hey Larry, Finally got around to checking this out. Question: // Index will be executed by all pages using the Home template.// Except if a page-specific method is defined (see below)// This function MUST be defined in your template controller. How does PW call a page-specific method? ie: foo_bar Thanks! Link to comment Share on other sites More sharing options...
larrybotha Posted September 11, 2014 Author Share Posted September 11, 2014 Hi Mackski! The page-specific method is being called by the MVC framework, not by PW itself! Let's say you have a page with a name of /i-really-enjoy-carpeting using a template called 'carpeting'. Inside carpeting_controller.php you could then have the following: # carpeting_controller.php.php class CarpetingController extends ApplicationController { function page_i_really_enjoy_carpeting() { return $this->render(); } function index() { ... } } What happens before a page is rendered is the call() method inside core/controller.php checks to see if there exists a method matching the snake-cased version of the current page name, prepended by 'page_'. If so, it will use that method instead of index() in the controller, allowing you to set variables and use templates for that page only. i.e. if the current page's name is i-really-enjoy-carpeting, and a page_i_really_enjoy_carpeting() method exists in the controller, use that method to process logic for that page. Link to comment Share on other sites More sharing options...
spoetnik Posted December 9, 2014 Share Posted December 9, 2014 I think this is an amazing setup. It was a bit of a steep learning curve for me, it was my first experience programming MVC. I must say it works sweet, changing layouts is a breeze with the logic in the controllers. I love it and thinks this deserves way more attention! Link to comment Share on other sites More sharing options...
larrybotha Posted December 10, 2014 Author Share Posted December 10, 2014 Glad to hear it's worked out nicely for you, @spoetnik! Thanks for opening that issue on Github - if you come across anything else, please open an issue or feel free to send through a pull request Link to comment Share on other sites More sharing options...
larrybotha Posted March 13, 2015 Author Share Posted March 13, 2015 We've now added cache busting for all assets in our boileplate. This means that in production, if an asset has been added to a manifest in the assets/ folder, your site will now serve an MD5'd version of the file. i.e. style.css -> style-18925h5bsdfsdfn.css No worries about appending query strings or force refreshing to get the latest asset, it's all done for you. Use of the manifest is optional. If an asset is not being rev'd in the manifest, it will be served with the filename you provide. e.g.: <!-- if this asset is not in the manifest, it will be served as assets/img/logo.svg --> <link rel="logo" type="image/svg" href="http://<?= $config->httpHost . $this->assets('img/logo.svg') ?>"/> <!-- if this asset IS in the manifest, in production it will be served as assets/css/style-9n183he.css --> <link rel="stylesheet" type="text/css" href="<?= $this->assets('css/style.css') ?>" > For an asset to be eligible for rev'ing, it must be accessed through the assets helper in views / templates: $this->assets('path/to/my/asset.ext') This is used best in conjunction with some sort of task automation, for which we have a Yeoman generator which generates a project with a Gulpfile that handles all the rev'ing of assets without any additional work for you: https://github.com/fixate/generator-fixate-pw (and more specifically, the gulpfile: https://github.com/fixate/generator-fixate-pw/blob/master/app/templates/_gulpfile.coffee) To create the manifest, you can run the following from the command line: $ gulp build You're now ready to deploy with your cache busted assets. Assets that are being rev'd by Gulp are css, js, images, and fonts (even handles rewriting paths in your css). Happy cache busting! 4 Link to comment Share on other sites More sharing options...
WinnieB Posted March 14, 2015 Share Posted March 14, 2015 Looks interesting, Larry Botha! I'm familiar with MVC from playing with some Python frameworks, and I'm getting to the point where tools like Yeoman make sense. Also, the graphics on your site look wonderful. Link to comment Share on other sites More sharing options...
bfncs Posted March 18, 2015 Share Posted March 18, 2015 Hi Larry, thank you loads for going through the efforts of putting this together. I've been experimenting with different ideas of implementing *VC along Processwire again and again, but was never really satisfied. Glancing at your solution it looks like it might be what I was looking for. I'm definitely going to try it out for the next smaller project. Link to comment Share on other sites More sharing options...
larrybotha Posted March 19, 2015 Author Share Posted March 19, 2015 thanks @WinnieB Yeoman's great for automating the dirty work and getting right to business. @boundaryfunctions great to hear it may be of use to you! It's very much based on Rails, and our new manifest feature is reminiscent of Sprockets / Asset Pipeline (but way faster thanks to Node and Gulp). Make sure to check out the wiki on the repo on Github - it's a little rough around the edges, but it should get you going a bit faster. 1 Link to comment Share on other sites More sharing options...
studioweb Posted October 22, 2016 Share Posted October 22, 2016 Hi Larry, did you manage to get this setup work in the PW 3.x branch? I'm getting 'Error: Class 'Environment' not found' Link to comment Share on other sites More sharing options...
larrybotha Posted October 24, 2016 Author Share Posted October 24, 2016 @Nico Smit our last PW project was released when 3.x was not yet stable, so we haven't yet toyed with the latest stable branch of PW. We'll be starting one or two new PW sites in the coming months, but with our current backlog I'm not sure we'll be getting there any time soon! In my spare time I'm building a project for our company on PW which will be starting in the next couple weeks, so I'll have to ascertain how quickly I can resolve those issues. If it's not too much trouble (I think it may come down to refactoring how our classes are instantiated / namespaced) I'll update the boilerplate then, but with our deadlines I may be forced to carry on with 2.x until I do get the time. @Nico Smit if you can open an issue, or even make a pull request it would be much appreciated! 1 Link to comment Share on other sites More sharing options...
larrybotha Posted November 3, 2016 Author Share Posted November 3, 2016 (edited) @Nico Smit I took a look last night at 3.x with the MVC framework - I ran into a few issues where previously global ProcessWire functions weren't available, such as `wire` and `wireEncodeJSON` in `traits/search.php` and `controllers/javascript.php` (there'll be a couple other files, such as `traits/forms.php`, but I haven't yet scoured all the files), but the issue was remedied by adding the ProcessWire namespace to those files, and using the namespace to access the functions: <?php # traits/search.php use ProcessWire as PW; ... # changed from wire(...) to: PW\wire(...); I didn't have any issues with `Error: Class 'Environment' not found`. I did an install using our generator. UPDATE 06/11/2016: Just released 0.5.9 which adds fixes for the global `wire` calls in the boilerplate: https://github.com/fixate/pw-mvc-boilerplate/releases/tag/0.5.9 Edited November 6, 2016 by larrybotha added note about updating the boilerplate repo 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now