Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/12/2013 in all areas

  1. In pw, if something is being too complicated you're probably doing it wrong
    6 points
  2. There was a thread elsewhere concerning some type of showcase for ProcessWire sites. I found the following in my G+ feed today
    4 points
  3. Thanks for letting us know. That's cheap enough to make me jump. Already had a namecheap account, so went ahead and registered a few that were still available: runs.pw (maybe a sites directory?) grab.pw (fwd to the github maybe?) mods.pw (fwd for the modules dir) processwire.pw (why not) skyscrapers.pw (for the demo site) skyscraper.pw (for the demo site) wires.pw (who knows?) Anyone else find or buy any good ones?
    4 points
  4. See also this thread with hooks for page access rights: http://processwire.com/talk/topic/371-page-specific-permissions There's a PagePermission.module that has all the permission hooks set for reference you might look in there. All permission hook: $this->addHook('Page::editable', $this, 'editable'); $this->addHook('Page::publishable', $this, 'publishable'); $this->addHook('Page::viewable', $this, 'viewable'); $this->addHook('Page::listable', $this, 'listable'); $this->addHook('Page::deleteable', $this, 'deleteable'); $this->addHook('Page::addable', $this, 'addable'); $this->addHook('Page::moveable', $this, 'moveable'); $this->addHook('Page::sortable', $this, 'sortable'); So most simple and basic delete module would be an autoload module as Wanze mentioned. //... public function init() { $this->addHook('Page::deleteable', $this, 'deleteable'); } public function deleteable(HookEvent $event){ $page = $event->object; if($page->id == 1001) { $event->return = false; } } So if on page with id 1001, there would be no delete function. $event->return should either be false or true and you can do all sorts of checks, for roles, users, permission, shoe sizes...
    4 points
  5. grab.pw should definitely always point to a zip of the latest stable release. wget http://grab.pw
    3 points
  6. EDGE is a responsive site designed by Salvato + Coe Group and developed by myself: http://edgela.com/
    3 points
  7. What was that again about PW API being jQuery-inspired? Yeah!, Write Less, Do More!
    3 points
  8. I think the easiest queries you can build with a template structure that is the following: Template artist - title - genre (Page field with template genre) - other metadata from artist Template album - title - artist (Page field with template artist) - cover (image) Template track - title - tracknumber - tracklength - file (mp3) - album (Page field with template album) Template genre - title This way, you have all your pages on a separate "branch" in your tree - but the data is related through page fields. +Artists --+ artist1 --+ artist2 +Albums --+ album1 --+ album2 +Tracks --+ track1 --+ track2 +Genres --+ genre1 --+ genre2 Sample queries: // Search for artists $artists = $pages->find("template=artist, title=Metallica|Queens of the Stone Age"); // Search 50 random tracks by artists with genre Rock $genre = $pages->get("template=genre, title=Rock"); $artists = $pages->find("template=artist, genre=$genre"); //If you have lot's of artists, you should limit here too and select random artists $tracks = $pages->find("template=track, artist=$artists, sort=random, limit=50"); // Get all albums of an artist $albums = $pages->find("template=album, artist.title=Dieter Bohlen") The issue with the track that doesn't belong to an album could be solved by creating an album "unknown" per artist and reference this album in the track. Did I already say that I love ProcessWire?
    3 points
  9. Just wanted to share what I recently used to create forms in modules and in frontend using the API and Inputfield modules PW provides and uses on its own. I think many newcomers or also advanced user aren't aware what is already possible in templates with some simple and flexible code. Learning this can greatly help in any aspect when you develop with PW. It's not as easy and powerful as FormBuilder but a great example of what can be archieved within PW. Really? Tell me more The output markup generated with something like echo $form->render(); will be a like the one you get with FormBuilder or admin forms in backend. It's what PW is made of. Now since 2.2.5~ somewhere, the "required" option is possible for all fields (previous not) and that makes it easier a lot for validation and also it renders inline errors already nicely (due to Ryan FormBuilder yah!). For example the Password inputfield already provides two field to confirm the password and will validate it. De- and encryption method also exists. Or you can also use columns width setting for a field, which was added not so long ago. Some fields like Asm MultiSelect would require to also include their css and js to work but haven't tried. Also file uploads isn't there, but maybe at some point there will be more options. It would be still possible to code your own uploader when the form is submitted. Validation? If you understand a little more how PW works with forms and inputfields you can simply add you own validation, do hooks and lots of magic with very easy code to read and maintain. You can also use the processInput($input->post) method of a form that PW uses itself to validate a form. So getting to see if there was any errors is simply checking for $form->getErrors();. Also the $form->processInput($input->post) will prevent CSRF attacks and the form will append a hidden field automaticly. It's also worth noting that processInput() will work also with an array (key=>value) of data it doesn't have to be the one from $input->post. Styling? It works well if you take your own CSS or just pick the inputfields.css from the templates-admin folder as a start. Also the CSS file from the wire/modules/InputfieldRadios module can be helpful to add. And that's it. It's not very hard to get it display nicely. Here an code example of a simple form. <?php $out = ''; // create a new form field (also field wrapper) $form = $modules->get("InputfieldForm"); $form->action = "./"; $form->method = "post"; $form->attr("id+name",'subscribe-form'); // create a text input $field = $modules->get("InputfieldText"); $field->label = "Name"; $field->attr('id+name','name'); $field->required = 1; $form->append($field); // append the field to the form // create email field $field = $modules->get("InputfieldEmail"); $field->label = "E-Mail"; $field->attr('id+name','email'); $field->required = 1; $form->append($field); // append the field // you get the idea $field = $modules->get("InputfieldPassword"); $field->label = "Passwort"; $field->attr("id+name","pass"); $field->required = 1; $form->append($field); // oh a submit button! $submit = $modules->get("InputfieldSubmit"); $submit->attr("value","Subscribe"); $submit->attr("id+name","submit"); $form->append($submit); // form was submitted so we process the form if($input->post->submit) { // user submitted the form, process it and check for errors $form->processInput($input->post); // here is a good point for extra/custom validation and manipulate fields $email = $form->get("email"); if($email && (strpos($email->value,'@hotmail') !== FALSE)){ // attach an error to the field // and it will get displayed along the field $email->error("Sorry we don't accept hotmail addresses for now."); } if($form->getErrors()) { // the form is processed and populated // but contains errors $out .= $form->render(); } else { // do with the form what you like, create and save it as page // or send emails. to get the values you can use // $email = $form->get("email")->value; // $name = $form->get("name")->value; // $pass = $form->get("pass")->value; // // to sanitize input // $name = $sanitizer->text($input->post->name); // $email = $sanitizer->email($form->get("email")->value); $out .= "<p>Thanks! Your submission was successful."; } } else { // render out form without processing $out .= $form->render(); } include("./head.inc"); echo $out; include("./foot.inc"); Here the code snippet as gist github: https://gist.github.com/4027908 Maybe there's something I'm not aware of yet, so if there something to still care about just let me know. Maybe some example of hooks could be appended here too. Thanks Edit March 2017: This code still works in PW2.8 and PW3.
    2 points
  10. A very simple tip, but that might be useful for someone that didn't think of it... This is what I usually do if I want to change something on a live site. if($user->name!='diogo'){ // live code }else{ // my new code } Like this I'm the only one that sees the changes. More examples: // test new javascript. do the same for styles <?php if ($user->name!='diogo'){?> <script src="<?php echo $config->urls->templates?>scripts/main.js"></script> <?php }else{?> <script src="<?php echo $config->urls->templates?>scripts/main-dev.js"></script> <?php }?> // test new head file if($user->name!='diogo'){ include(head.inc); }else{ include(head-dev.inc): } and so on... edit: corrected the first block by Nik's suggestion
    2 points
  11. That's an "easy" task in Pw because you don't have to write SQL but find your stuff with selectors. Basically you just throw your data that was sent with the selects in a Pw selector to get your pages: // In template (HTML) <form method="GET" action="<?= $page->url ?>"> <select name="gender"> //.. options </select> <select name="color_hair"> //.. options </select> <select name="age"> //.. options </select> </form> // In template, above output if (count($input->get)) { // Get the criteria and sanitize them $gender = $sanitizer->selectorValue($input->get->gender); $color_hair = $sanitizer->selectorValue($input->get->color_hair); $age = $sanitizer->selectorValue($input->get->age); // Search pages $p = $pages->find("template=user, gender=$gender, color_hair=$color_hair, age=$age"); } This is a simple example. If you have some select fields optional, you'd need simple logic to check if the data was sent. And just add it to the selector if the user submitted the criteria.
    2 points
  12. Hi Ollie, I am not using the Processwire minify module, but this solution: https://github.com/mrclay/minify In the HTML the different javascript files need to be output like this to trigger the minification (works also with CSS files): <script type='text/javascript' src='/min/?b=sovonex/site/templates/js&f=jquery-1.9.1.min.js,tabs-accordion/index.js,tabs-accordion/jquery.ba-resize.js,tabs-accordion/tabs-accordion.js,jquery.placeholder.min.js,include.js'></script> Cheers, Stefan
    2 points
  13. ProcessWire DataTable 1.0.0 (https://github.com/somatonic/DataTable) This module enables you to find and edit (fancybox modal iframe) pages at a small and very large scale. So far it has: ajax suuport masked pagination state saving (datatable using cookie, template filter using session) template filter (only showing templates user has edit access) search text filter (using title|body field) multilanguage support (PW's language translator) Superuser will see all pages and system templates. Users only those with view|edit access and pages in trash. This Module is still very simple and only in "lazy" developement and testing and this is the first official release mainly to get it out for others to see and use. It also could provide as an example/kickstart for someone. Everyone is encouraged to help and contribute to further improve or add features. The module is hosted on my github account: https://github.com/somatonic/DataTable The plugin used in this module is the excellent jQuery Plugin DataTable 1.8.2 - http://datatables.net/ I've chosen it, because I used in in some other web projects and was really happy about it's power and ease to setup. It supports jQuery UI styling, which makes the deal perfect for a ProcessWire module. Thanks and have fun trying it out. ------ (original post, kept for nostalgic moments) Ok, I started trying to implement the great jQuery dataTables plugin into ProcessWire. So far it works very well and is very powerful and fun. Best of it it support jquery themeroller. Not sure how far this all can go with configuration and how to define which pages should be displayed, what collumns etc... Many many things to consider. But if it could provide as an example on how to implement it, it would be great tool for site builders. Here you can see a short video of how it looks and works.
    1 point
  14. I registered selector.pw a while back. I've got an idea of some kind, but we'll see if I'm ever able to get anything up and running there...
    1 point
  15. There's no way as far as I know, built-in one that is. I thought I'd seen a conversation on this subject but couldn't find one right away. This one may be helpful if you're creating pages programmatically though.
    1 point
  16. I stand corrected - good lesson for me there diogo Very true though - that is what I love about PW - the way custom PHP is so easily implemented. All the flexibility of a fully custom coded site, with all the benefits of a CMS!
    1 point
  17. Hi jmart, You could go with an autoload module that hooks into Pages::___delete() I'd write the array with the id's in /site/config.php This is just an example - not tested. Maybe there exists more elegant solutions? //... in your autoload module public function init() { $this->pages->addHookBefore('delete', $this, 'checkDelete'); } public funciton checkDelete($event) { $page = $event->arguments[0]; $id = $page->id; if (in_array($id, $this->config->doNotDeleteArray)) { throw new WireException("Sorry but you can't delete this page!"); } }
    1 point
  18. You can put a checkbox on the home page, or a config page, and then something like this in the head.inc (adapt to your situation): if($maintenance && $user->isGuest()) $session->redirect($page->get('/maintenance/')); These tricks can also be tweaked to that effect http://processwire.com/talk/topic/2475-quick-tip-for-testing-on-live-website/ edit: adrian, in pw there is always an alternate way
    1 point
  19. @adrian: that would be far too simple. Looking for a more difficult method. Thanks will go give it a try. Solved Thanks @adrian, it worked like a charm!
    1 point
  20. I haven't looked over the shuffleAssoc function properly, but you can probably just use PW's shuffle(): $randimages = $bannerimages->shuffle();
    1 point
  21. On mobile so short. Yes you have to remove or edit the fields name restriction check in the hook function for the multi select. Line 59 in module. It's hard coded and also other hooks i was experimenting are commented out. Back on laptop https://github.com/somatonic/PageReferenceLink/blob/master/PageReferenceLink.module#L59 ... screw it I just updated it and commented out the check so all InputfieldPageListSelectMultiple fields will have an edit link. This module is just experimental prototype but working and a start.
    1 point
  22. This thread and this wiki page might help with explaining render(); Hope this helps
    1 point
  23. @jmart - if there are not a lot of pages, don't nest the pages in the admin, but then make a custom menu. That's how it do it on 3 sites now. (in other words make all of the pages child of the root.) As far as making the custom menu, i do it the way discussed in this thread, and works perfectly. You have to adjust the code to your specific menu needs.. http://processwire.com/talk/topic/2787-custom-menu-not-related-to-page-tree/ i also wanted to mention that once you have a lot of pages in the admin, you could use Soma's datatable to look for pages, instead of the tree; then you could filter/sort by some criteria (title, template); so in this sense you would using PW as more of a bucket system... which for some projects is good, and PW handles it fine...
    1 point
  24. I really have three tips: 1) Find a good professional accountant who you can trust (preferably through a contact) 2) Find a good professional lawyer who you can trust (preferably through a contact) 3) Find someone in your network who already has set up a profiting business. If you ask you'll be surprised how open people are in general. These guys will save you money in the long run.
    1 point
  25. I know you are from south and middle England, but every time you both talk I imagine this accent https://www.youtube.com/watch?v=RL4FCRbm5jo
    1 point
  26. Ha, the awesome Soma made this autoload module which adds the properties to the page: https://gist.github.com/5166076 so you can do: $page->is_hot =D
    1 point
  27. Well, ProcessWire is far more flexible than that! Starting at a very basic level, you could create fields in your main template that you would then use in a sidebar for instance: sidebar_title sidebar_text sidebar_image or whatever you wanted. If those are included in the templates you are using, then those fields are available for all the pages that use those template - if you don't use them, they wont display anything. Next level up! You can pull content from any page. So, you could create a specific page with a specific template (but no associated template file) and use it for some global fields. For instance it could have a textarea called "extra_info" into which you add something you want to appear on many pages. In the template file for those pages you would call that field in this way: echo $pages->get("/my-global-page/")->extra_info; Getting more complicated Next up, you can use a Page field to drag in an entire page, or series of pages. For instance, you create a block template (complete with file) and give it a handful of fields. In the associated template file, you would only put in the mark-up needed to render that particular block - no header or footer or anything like that. You can use that template to create a series of blocks. You now create a page field which you will use to select one or more of those blocks. You can set up the page field to look for pages under one particular parent, or by one particular template - so you can restrict what is selected. Add that field to the template for your normal pages. Edit one of those pages and you can select a block. In the template file for your normal pages, you can now grab the contents of that field as normal, but then render the output: echo $page->mypagefield->render(); That will output the selected page, rendered in its own template. From that point you can get really imaginative. You can use the page field to select multiple pages and then use a foreach loop to render them all out. You can set up your normal page templates so that you can choose blocks for individual pages, or by perhaps putting the page field in a central source (like I did at the head of this answer), maybe make it a global block system You really can do anything you want, render things as complete pages or just pull particular fields out ... and so on. This demo site I did is done completely with blocks that are then selected from a central source: http://pwdemo3.stonywebsites.co.uk/ So, yes - it is all possible, and without having to go near a plugin. Joss
    1 point
  28. I used to use a shopping cart software and I thought if I give you some of the set up options from that, it might help you configure a module for PW. First see attached document that shows the basic tax set up for that software. Some of the main set up selections are listed below: TAX MODE Simple or Advanced (select one) SIMPLE TAX Enter a description e.g VAT Enter a message e.g VAT payable on all UK orders Enter a % Rate e.g 20.00 ADVANCED Product Prices Entered Price inclusive of tax or Price exclusive of tax (Select one) Taxes Enter name e.g VAT Tax Rounding Level - Line Item Order (select one) Tax Rounding Method - Truncate, Round Half Down, Standard, Round Up, Banker's Rounding (select one) Tax By Location Always apply taxes, Tax by delivery address, Tax by Invoice address (select one) Tax Zones Add a Zone (you can add multiple zones) - Enter name e.g UK, select countries to be included in that zone e.g England, Scotland, Wales, Northern Ireland and save it. Then in Shipping and Handling section you would select shipping charges made - yes or no. If yes, choose the Tax Rate e.g VAT (as defined in Taxes above, Zero Rated, Exempt, Custom. If custom is selected enter custom rate. Select if handling charges are made. If yes, select Tax Rate (same as for Shipping selection). Then we get into Shipping configuration e.g Simple or By Zone and Class. That's a bit more complicated e.g Simple is a fixed charge e.g. 5.00EUR, By Zone and Class uses various methods like by weight classes and you can set up different postal charges e.g UK - First Class UK - Second Class UK - Standard Parcel etc. There's more info here I hope that helps. Let me know if you need any clarification. tax_set_up.doc
    1 point
  29. Sorry my fault. I haven't read careful and assumed from your selector that you have authors with a page field "posts" to reference all posts. It's the other way round then. But having it the way I assumed would result in having a simpler code Don't worry, you could either change it if you like it or use this with current (like nico but little improved I think) $authors = $pages->find("template=authors"); // create empty page array $res = new PageArray(); foreach($authors as $a) { // temporarely add postscount property to author $a->postcount = $pages->count("template=posts, author=$a"); $res->add($a); } foreach($res->filter("sort=-postcount, limit=5") as $a){ echo "<p>$a->title ($a->postcount)</p>"; } Let me know if it works for you.
    1 point
  30. I found Janko's FormToWizard code to be one of the simplest ways to implement a multi-page/multi-slide form. Now with the Processwire this just got easier. I tweaked his script a wee bit to work with the API forms described in this thread. PWformToWizard.js bunching your fields into fieldsets just as Ryan described above, each fieldset will become a page/slide. Instead using the <legend> tag that Janko uses, the script now generates a legend based on the label, specifically anything that comes before a colon ':' first add the script: <script type="text/javascript" src="PWformToWizard.js"></script> then use this javascript to initiallize formToWizard: $("#SignupForm").formToWizard(); the default styles are: <style type="text/css"> body { font-family:Lucida Sans, Arial, Helvetica, Sans-Serif; font-size:13px; margin:20px;} #main { width:960px; margin: 0px auto; border:solid 1px #b2b3b5; -moz-border-radius:10px; padding:20px; background-color:#f6f6f6;} #header { text-align:center; border-bottom:solid 1px #b2b3b5; margin: 0 0 20px 0; } fieldset { border:none; width:320px;} legend { font-size:18px; margin:0px; padding:10px 0px; color:#b0232a; font-weight:bold;} label { display:block; margin:15px 0 5px;} input[type=text], input[type=password] { width:300px; padding:5px; border:solid 1px #000;} .prev, .next { background-color:#b0232a; padding:5px 10px; color:#fff; text-decoration:none;} .prev:hover, .next:hover { background-color:#000; text-decoration:none;} .prev { float:left;} .next { float:right;} #steps { list-style:none; width:100%; overflow:hidden; margin:0px; padding:0px;} #steps li {font-size:24px; float:left; padding:10px; color:#b0b1b3;} #steps li span {font-size:11px; display:block;} #steps li.current { color:#000;} #makeWizard { background-color:#b0232a; color:#fff; padding:5px 10px; text-decoration:none; font-size:18px;} #makeWizard:hover { background-color:#000;} </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script> <script type="text/javascript" src="formToWizard.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#SignupForm").formToWizard({ submitButton: 'SaveAccount' }) }); </script> see janko's page for more info~ Now, just to add some responsive jquery validation to each 'next' button...
    1 point
  31. Great tutorial Soma! This is the best summary of using PW's Inputfields that I've seen. I noticed you did $field->attr('id+name', 'email') so just wanted to explain what that is for those that may be unsure of the syntax. That syntax is basically saying to set the 'id' and 'name' attribute to have the 'email'. While every field needs a 'name' attribute (like in HTML) the 'id' attribute is optional… if you don't assign an id attribute, PW will make one up. If you intend to custom style a field with CSS or target it from javascript, then it's best to assign your own 'id' attribute. Otherwise, it doesn't matter. // this… $field->attr('id+name', 'email'); // …is the same as: $field->attr('id', 'email'); $field->attr('name', 'email'); // …as is this (direct reference): $field->id = 'email'; $field->name = 'email'; The advantage of using the attr() function over direct reference is that attr() can't ever collide with other Inputfield properties that might have the same name as a field attribute. It's basically your way of saying "this should definitely be an HTML attribute and not anything else." For recognized attributes like 'name' or 'value' it doesn't matter what syntax you use because an Inputfield already knows 'name' and 'value' are standard HTML attributes. But if you needed to add a custom attribute like "data-something", well then you'd definitely want to use the attr() method of setting. That attr() method should only be used for things that would actually be HTML attributes of the <input>, because they will literally end up there. So if you do an $field->attr('label', 'Hello'); you'll end up with an <input label='Hello'> in the markup, which is obviously not something that you want. That's why you assign a non-attribute property like 'label' or 'description' directly, like: $field->label = 'Something'; Last note about $attr() is that it can be used for both setting and getting attributes: $field->attr('value', 'something'); echo "The field's value is: " . $field->attr('value'); // same as: $field->value = 'something'; echo "The field's value is $field->value"; To extend your example, lets say that you wanted the 'email' and 'password' fields in a fieldset titled "About You". You would create the fieldset, and then add/append the fields to the $fieldset rather than the $form. Then you'd add the $fieldset to the $form: $fieldset = $modules->get('InputfieldFieldset'); $fieldset->label = 'About You'; $field = $modules->get("InputfieldEmail"); $field->label = "E-Mail"; $field->attr('id+name','email'); $field->required = 1; $fieldset->append($field); // append the field $field = $modules->get("InputfieldPassword"); $field->label = "Password"; $field->attr("id+name","pass"); $field->required = 1; $fieldset->append($field); $form->append($fieldset); Or lets say that you wanted those 'email' and 'password' fields to be each in their own column so that are next to each other horizontally rather than vertically. You would assign the 'columnWidth' property to both the email and password fields. In this case, we'd give them both a value of 50 to say that we want them to be a 50% width column: $field->columnWidth = 50; To jump out of tutorial mode and into idea mode: lately I've been thinking that PW should have a YAML to Inputfields conversion tool in the core (something that would be pretty easy to build), so that one could define a form like this: And create it like this (where $yaml is the string above above): $form = $modules->get('InputfieldForm'); $form->load($yaml); echo $form->render();
    1 point
  32. There is a way. // first get parent and it's first child $parent = $pages->get(1001); $first = $parent->child; // create new page with same sort as first child $p = new Page(); $p->template = $templates->get("basic-page"); $p->parent = $parent; $p->title = "Make me first"; $p->sort = $first->sort; $p->save(); // move first child to second position $first->sort++; $first->save(); Now your new page is at first position. However this only work if you got manual sorting on parent of course.
    1 point
  33. You can also use an import method of PageArray. Note that the page array of PW isn't a regular php array, that's why it doesn't work. you could also do something like this. $pa = new PageArray(); $pa->import( $pages->get("/content/")->children() ); $pa->import( $pages->get("/footer/")->children() ); foreach($pa as $p){ ... } You may check out the cheatsheet on the API pages, and look for the PageArray/WireArray sections. There's lots of useful methods. For example instead of this: $contentpages = $pages->get("/content/")->children; unset($contentpages[0]); do this to slice off the first entry in the resulting page array: $contenpages = $page->get("/content/")->children()->slice(0);
    1 point
  34. The new user system will provide better support for developing your own user registration functions. But it's probably still a month or so before I'll have that ready. In the new user system, users are actually pages, so you can interact with them, add fields to them, and so on, in the same way.
    1 point
×
×
  • Create New...