Leaderboard
Popular Content
Showing content with the highest reputation on 09/03/2013 in all areas
-
Or use this script I created to create and send a zip to browser. https://gist.github.com/somatonic/6427247 /* creates a compressed zip file */ function create_zip($files = array(),$destination = '',$overwrite = false) { if(file_exists($destination) && !$overwrite) { return false; } if(is_array($files)) { foreach($files as $name => $file) { if(!file_exists($file)) unset($files[$name]); } } if(count($files)) { $zip = new ZipArchive(); if(!$zip->open($destination, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE)) return false; foreach($files as $name => $file) { $zip->addFile($file,$name); } $zip->close(); return $destination; } else { return false; } } // get a language to export json files $lang = $languages->get("de"); $files_to_zip = array(); // "language_files" = file field on language page where json's are stored foreach($lang->language_files as $f){ $files_to_zip[$f->name] = $f->filename; } $zip = create_zip($files_to_zip, $config->paths->root . 'language_files_de.zip' ,true); if($zip) wireSendFile($zip); // send file to browser (/wire/core/functions.php) This would be put in a template file. Have fun. While doing this we might need a wireCreateZip() function in core as we also got a wireUnzipFile().4 points
-
Hi everybody, I have a setup where I have to assign one or more categories to a page. After spending some time wondering how I could make PW fields store lists, I decided upon keeping a serialized array in a page field (type = "text"). Here's how: $categories = array ("brushes", "watercolor", "pencils", "charcoal", "acrylics", "egg tempera",); $p = $pages->get(9999); $p->of(false); // the usual stuff... $p->category = serialize($categories); // transform the array of categories into a string $p->save(); unset ($categories); // wipe the slate clean for testing purposes // Now Let's Get 'em! $categories = unserialize($p->category); foreach ($categories as $c) echo $c . "<br />"; The array with the list of categories becomes a:6:{i:0;s:7:"brushes";i:1;s:10:"watercolor";i:2;s:7:"pencils";i:3;s:8:"charcoal";i:4;s:8:"acrylics";i:5;s:11:"egg tempera";} It can be stored in a page field and fetched as an array when needed. Neat! (Just remember to set MaxLength to a higher value if you intend to use "text" fields for this purpose.) Thanks for reading!3 points
-
Sound strange as I don't see what you can do with yii what you can't with PW. It a bit like using yii with laravel.3 points
-
Soma thanks for the troubleshooting here. I think we can solve both issues by having the LanguageSupportPageNames module hook into both $pages->saveReady() and $pages->saved(). It'll set an active status for all users/roles/permissions before one is saved, as well as record the current language setting. Then the $pages->saved() hook will restore that language setting. I will implement these updates later today.3 points
-
Hi i3i2uno, Welcome to PW and to the forums MySQL could indeed be the issue regarding the 500 error. As per the requirements, PW needs MySQL 5.0.15 or greater (later versions of 4.x may also work). It could be other stuff as well, .htaccess. Did that transfer correctly? is it named correctly? Maybe the rules there are conflicting with GoDaddy server? Missing files? As for connecting to a remote db, never tried that so can't comment Edit: Some GoDaddy issues here: http://processwire.com/talk/topic/1962-cant-reach-admin-page/ http://davidwalsh.name/mod_rewrite-htaccess-godaddy Possibly related/or for info http://processwire.com/talk/topic/82-install-pw-to-subdir/ http://processwire.com/talk/topic/3258-moving-website-from-local-server-to-a-sub-domain/2 points
-
I would welcome the possibility of choosing a theme per role or user, like this we could build customized themes only for clients without worrying about a big part of the system (template editing, modules page, etc). From there, even deeper changes could be done.2 points
-
To justify the optional sidebar: Screens under 1200px will not see the sidebar. It will be hidden by default. I've set the first offset margin to 15px and then increase the margin by 20px each level. On a 1280px Screen with 1/3 sidebar I get around 425px. On a 1920px Screen (24" HD Office) I will have 640px for the sidebar. The "problem" are different lenghts for the text + the edit|view|new buttons. Question: How many sublevels do you usually have? I like that aspect. In the next version of the concept I've stripped down some icons. I'm using them for arrows and the template type of a page. I think, it's the tiniest way to display the "type" of template of a page.If not, my customer just thinks of pages and not of galeries,blog posts, news, products,... The top bar is now white. I've chosen the pink/magenta color for everything that has an action, the blue colorto indicate things. The font size also went done from 18px to 16px and the overall look is now a little bit more compact. The second screenshot demonstrates a 1280px window size. This would be a great start. Especially with the theme switcher for the upcomming versions. We could quick build a custom view for a client. Another thing to the "Admin Kit". Maybe the admin-themes can get some sort of an option page where we can disable things like the sidebar. Not sure about this one...2 points
-
To problem 2. After testing we found that in where the language suddenly changes from "fr" to "default" is where we in API modify a user (not current) and save it. Afterwards the $user->language is set to "default" of the current user. THe culprit seems to be that after $page->save() there's a uncacheAll called which cleans out the $user->language set on runtime. We have now a workaround to save language before to a var, and give it back to the $user after the save. But it looks like when saving a user in front-end the $user->language set by the language system is reset.2 points
-
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.1 point
-
Field dependencies are coming in ProcessWire 2.4, and I just wanted to give you guys a little preview of it. The development of this new feature is being sponsored by Avoine, the company where Antti works (he also specified how it should work). Field dependencies are basically just a way of saying that one field depends on another. It dictates which fields should be shown in a given context. In our case, it also gets into whether a field is required or not. This short video demonstrates how it works: (switch to the 720p and full screen version, as YouTube's default settings for this video make it impossible to see): // Edit @Adamkiss: Here's link for those on mobile: youtu.be/hqLs9YNYKMM The implementation here is done both client-side and server side. Javascript handles the showing/hiding of fields and the required vs. not required state changes. On the server side, it doesn't process any fields that aren't shown, and honors the required rules. A separate processing occurs both client side and server side, ensuring that the user can't make their own rules by manipulating the markup or post data. These field dependencies can be used with any Inputfield forms. That means you'll be able to use it not just in ProcessWire, but in FormBuilder, and via the API too. It's very simple to use from the API. All you have to do is specify a ProcessWire selector to either "showIf" or "requiredIf" to the Inputfield, and ProcessWire takes care of the rest: // show this field only if field 'subscribe' is checked $inputfield->showIf = "subscribe=1"; // show this field only if 'price > 0' and at least one category selected $inputfield->showIf = "price>0, categories.count>0"; // make this field required only if 'email' is populated $inputfield->required = true; $inputfield->requiredIf = "email!=''"; This feature will be in the 2.4 core (rather than as a separate module), so it will also be ready and available for things like module and field configuration screens.1 point
-
This tutorial will outline how to create a membership system that requires account activation via email. If you have a decent understanding of ProcessWire it isn't difficult at all! Create additional fields By default ProcessWire has a name, email, and password field for the user template. To allow for account activation we will have to add a couple more fields. Create the following fields and add them to the systems default user template. You can make ProcessWire show the system templates by going to setup -> templates -> toggle the filter tab -> show system templates -> yes. user_real_name user_activation Okay great, now that you have added the two additional fields to the user template we can start to code the registration form. I am not going to spend a lot of time on this part, because there is a tutorial that describes creating forms via the API. Create the registration form Once you have followed the tutorial on creating forms, you will have to add a couple of sections to your new form! <?php include("./functions.php"); require("/phpmailer/class.phpmailer.php"); $out = ""; $errors = ""; //create form //full name field //email field //username field //password field //submit button //form submitted if($input->post->submit) { $form->processInput($input->post); //instantiate variables taking in the form data $full_name = $form->get("full-name")->value; .... /* * Create the activation code * You can add a random string onto the * the username variable to keep people * from cracking the hash * ex $activation = md5($username."processwire"); */ $activation = md5($username); $activation_code = $config->httpHost."/activation/?user=".$username."&hash=".$activation; //check for errors if($form->getErrors() || username_validation($username) == 0) { $out .= $form->render(); //process errors /* * this checks to makesure that no one has the username * I have a functions file that I import to the pages I * need it on */ if(strlen($username) != 0){ if(username_validation($username) == 0) { $username->error = " "; $errors .= "Sorry that username is already taken!"; } } } //the registration was successful else { $out = "Thank you for registering!<br><br>"; $out .= "An email has just been sent to " . $email . " with the url to activate your account"; /* * In this example I am using phpmailer to send the email * I prefer this, but you can also use the mail() function */ $mail = new PHPMailer(); $mail->IsHTML(true); $mail->From = "email@domain.com"; $mail->FromName = "Register @ Your Site"; $mail->AddAddress($email); $mail->AddReplyTo("email@domain.com","Register @ Your Site"); $mail->Subject = "Registration"; $mail->Body = " Hi " . $full_name. ", <br>" . "Thanks for registering at Your Site. To activate your email address click the link below! <br><br>" . "Activation Link: <a href='http://".$activation_code."'>".$activation_code."</a>"; $mail->send(); //create the new user $new_user = new User(); $new_user->of(false); $new_user->name = $username; $new_user->email = $email; $new_user->pass = $password; $new_user->addRole("guest"); $new_user->user_full_name = $full_name; $new_user->user_activation = $activation; $new_user->save(); $new_user->of(true); } } //form not submitted else { $out .= $form->render(); } ?> <h2>REGISTER</h2> <div class="errors"><?php echo $errors; ?></div> <?php echo $out; ?> Okay so that outlines the entire form. Let me get into the important parts. Checking for a unique username /* * check if username exists * return 1 username is valid * return 0 username is taken */ function username_validation($username) { $valid = 1; $check = wire("users")->get($username); if ($check->id) { $valid = 0; } return $valid; } We don't want to try and add a username if the username is already taken, so we need to make sure to validate it. If this returns 0 you should output that the username is already taken, and the user needs to choose a different one. Generating an activation code /* * Create the activation code */ $activation = md5($username); $activation_code = $config->httpHost."/activation/?user=".$username."&hash=".$activation; This generates an activation code. It does so by encrypting the username variable and then combines the username and activation code into a url for a user to visit. Now we have to process the activation code. As the teppo recommended, it is a good idea to add an extra string onto the $username when encrypting it with md5. If you don't do this, people may crack it and allow for mass signups. $activation = md5($username."Cech4tHe"); Activate the user <?php include("./head.inc"); include("./functions.php"); /* * this will pull the username and * activation code from the url * it is extremely important to * clean the string */ $activate_username = $sanitizer->text($_GET['user']); $activate_hash = $sanitizer->text($_GET['hash']); if(wire("users")->get($activate_username)->id) { if(strcmp(wire("users")->get($activate_username)->user_activation, $activate_hash) == 0 || wire("users")->get($activate_username)->user_activation == 0) { echo "Your account has been activated!<br><br>"; $activate_user = wire("users")->get($activate_username); $activate_user->of(false); $activate_user->user_activation = "0"; $activate_user->save(); } else { echo "There was an error activating your account! Please contact us!<br><br>"; } } else { echo "Sorry, but that we couldn't find your account in our database!<br><br>"; } include("./foot.inc"); This pulls the username and activation hash from the url. It then goes into the database and looks for the user. Once it finds the user, it get's the user_activation hash and compares it to the one in the URL. If it matches, it activates the user by setting user_activation to zero. Clean the url You can user the built in $sanitizer->text() method to clean the url. This will keep people from inserting special characters that can break the page. Keeping unactivated users out You aren't done yet! Now you will have to choose which areas you want to restrict to activated users only. An activated user's user_activation field will now equal zero. So if you want to restrict a section check to make sure it is zero...... if($user->user_activation != 0) { echo "Sorry, but you need to activate your account!"; } else { // activated users }1 point
-
MS is buying Nokia, what's left of the fallen giant... http://www.bbc.co.uk/news/business-23940171 http://www.bbc.co.uk/news/technology-239472121 point
-
Greetings, This is a terrific discussion, which opens up a lot of ideas in my mind. Over the past couple of years, I have spent a lot of time using various PHP frameworks (especially like Yii). I would agree with Soma that -- for the most part -- ProcessWire allows you to accomplish the same goals as these frameworks. There is a lot to say here, but I'll try to summarize: ProcessWire's Huge Advantage: Querying and Syntax I find that the syntax of ProcessWire is far more concise and "expressive" (borrowing a favorite Laravel term) than these PHP frameworks. The ability to design very deep queries really quickly and easily is the greatest advantage of ProcessWire. "Framework" vs "CMS" I believe ProcessWire should be described as a framework with crucial pre-built CMS components. Currently, ProcessWire is described as a CMS with a framework behind it. The problem is that when it is described as a CMS, we naturally see comparisons with WordPress, Joomla, and Drupal, and anyone who spends time with ProcessWire immediately realizes it is not the same type of thing as these CMSs. If it were presented as a framework, it would attract a whole different set of people with (I believe) more accurate assumptions. Future Development and Framework Choices Nothing replaces ProcessWire, but I gain something using other frameworks that I often can come back and use in ProcessWire. My very rapid framework rundown... CodeIgniter is essentially dead. Laravel, which seemed great at first, has become overly convoluted. Yii has the best balance as a framework, but when I compared the time and effort to get an application up and running in ProcessWire vs Yii, ProcessWire wins. Lately, I have been experimenting with PHPixie (yes, I am always trying new things), and it is really nice. In fact, I see a lot of similarities between PHPixie and ProcessWire. What Do Frameworks Have Over ProcessWire? The only "advantage" of PHP frameworks over ProcessWire is that frameworks have no back end at all. ProcessWire's back end is extremely minimal, and really does serve the most necessary elements. But when building custom UIs, I often want to just go directly to the database with no assumed page concept at all. With that said, I have developed a set of methods that nicely takes care of this in ProcessWire. And ProcessWire has such an elegant query and syntax system, it saves massive time overall as compared with one of these frameworks. So there is a bit more time getting your custom UI CRUD going, but after that you save huge time using ProcessWire's data-handling system. Sorry if this got a bit far from the direct subject, but it seems that people reading this thread might be asking some of the same questions I have asked about PHP frameworks and ProcessWire. Thanks, Matthew1 point
-
Philipp, looks great. Can you show how fields looks without that thin border/shadow and maybe with black/grey labels? I think we should aim for "less borders / boxes" feel. I really like your iteration, very clean looking!1 point
-
Well - here's actually the IDE that lets you simply code how it should. http://www.webuilderapp.com/ http://www.webuilderapp.com/highlights.php Makes coding (e.g. a website) no longer work, but a pleasure. Also makes this thread obsolete because of inbuild customizable Code Library and code folding http://processwire.com/talk/topic/1018-repository-of-php-scripts-for-templates/page-2#entry43079 And no I am not affiliated with them.1 point
-
There were more posts promoting this software on other threads, always by first time posters. It's a friendly spam, but it's still spam1 point
-
If I am understanding you correctly it is quite simple to do by setting a variable to the current category and then only echo out the category title if the category is different to the category from the last echo'd result. $current_category = ''; foreach($wor as $result) { if($result->cat != $current_category){ echo "<span class=\"catem\">{$result->cat->title}</span>"; } echo **all the name, location, result output** $current_category = $result->cat; } Hope that makes sense and works for you.1 point
-
I also think the tree as a sidebar presents its challenges, both on the design and coding aspects. Also, it generates more noise on the page. The ability to toggle it helps a lot. I think this is those kinds of decisions that generate some divide and aren't easily reconciled. Take a look at this example by Squarespace. It doesn't look very scalable, I guess. But my point of view is that other improvements that are talked here are sure to generate more goodness and acceptance. Things like bigger text and inputs, for example, place more focus on the content, which is always a good thing. It won't change the general structure of the admin, but certainly make it better. Aspects like iconography and color are included in Philipps and Nico's proposal, which I like a lot. This would still maintain the admin's clean and un-bloated look, which is an asset in this case. The idea of "building blocks" is very appealing because PW is a really modular system and that philosophy should be taken into account in the UI. Bootstrap, Foundation and other CSS frameworks take this idea of building blocks into account and are good examples. Those look like good starting points and inspiration in my opinion (even if they are not used, the organisation is very good). I imagine every admin PW like a grid full of widgets that can be closed/opened and have different interactions (page selection, image uploading, text input, etc). The tree is a whole different beast and UI improvements are already present in Philipps and Nico's proposals. We even talked about some stuff here: http://processwire.com/talk/topic/4292-search-filters-and-options-for-the-page-fieldtype/#entry42038 In all, I'm happy there's a discussion about this topic!1 point
-
1 point
-
Are you getting errors when trying to delete or add new repeater fields, or is just nothing happening? Sorry - you show the error in the subject I really haven't used repeater fields much at all, but if you are having problems deleting existing fields, you can do that through PMA as well. I wouldn't recommend deleting anything through PMA generally, but since you have already ventured in there and deleted all those pages, it sounds like that might have broken some things already anyway. Go into the "fields" table and delete the appropriate lines as well as deleting the "field_fieldname" tables. Or if you are cautious, wait for a more authoritative answer1 point
-
Nice job Philipp, I like where you are going with this. Thanks for putting your time and skills towards this. Having a new default admin theme is something I think we need to approach soon, and contributions like this are very much appreciated. I also think your work here is nice to look at and very well designed. With regards to an always visible page tree: not showing the page tree when in the page editor is very much a conscious decision. I recognize there are benefits and drawbacks and that it's a compromise either way. Here's the thinking of why we currently compromise on the side of not showing it: The default admin theme needed to be something that could scale near infinitely, and delegating the page tree to a sidebar introduces a lot of natural limitations (though none that scrollbars can't solve, but I'm not a fan of them). Another goal was to keep the user focused on the page they are editing by having the browse and edit states be very separate things. Lastly was the issue of overhead: generating a page tree involves a lot of work, and can contribute to making the admin feel slow… especially if having to generate it for every page edit. (Though this may be something caching could solve, but it could be tricky to develop: clearing such a cache after each page save might defeat the purpose). I did actually test out both SilverStripe and MODX before developing ProcessWire–I wasn't pleased with their page trees and really wanted to differentiate ourselves from that. Though your design here for the page tree does do that–it looks a whole lot better than what's in other systems. Those are some of the reasons why we'd decided not to show the page tree when in the page editor. But I recognize there are some real benefits: I like the possibility of being able to quickly jump between pages when needing to make edits to multiple pages or needing to add a bunch of pages. I also like the aspect of seeing where I am in the tree… While the breadcrumb trail accomplishes it, the tree can reinforce it. But these benefits were not enough to outweigh the benefits of not showing it. Still, if there is great demand, or if people would prefer the option, I'd be supportive of it as an option in the default admin theme. Though do wonder if a full-width, click-to-reveal panel at the top of the screen would better solve the scalability aspect? Whether sidebar or top-panel, if these things open only when hovered or clicked, we could solve the overhead problem by just doing it with ajax. For the Quick-Add button, I believe we could easily support this on any templates that have family settings defining a single required parent. When templates are configured that way, they could have a checkbox that says "Add to quick-action list?" or something along those lines. Keep up the great work. I look forward to seeing more.1 point
-
You might try adding this to the end of your /site/config.php: $config->sessionName = "sevarf2"; session_name($config->sessionName); session_set_cookie_params(0, '/', '.mydomain.com');1 point
-
1 point
-
I've gone ahead and committed the Inputfield dependencies to the dev branch, for anyone that would like to help test. I've also posted a documentation page that explains how and where to use them, current limitations and examples. There are a near infinite number of potential scenarios on how these things could be used, so it's not possible for me to test everything locally. As a result, expect bugs and please report them when you find them. Thanks in advance for your help in testing. For non-default admin themes, some updates have to be made in order to support field dependencies. As a result, unless you are an admin theme developer, it's best to stick to the default admin theme when using field dependencies, temporarily. Field dependencies can also be used in FormBuilder. Though I've not done a lot of testing in FormBuilder yet, so don't recommend using field dependencies in front-end production forms just yet. Though in my initial testing, they seem to work just fine. Thanks again to Antti/Avoine for sponsoring field dependencies!1 point
-
For us it is pure business: it is great to have possibility to buy (or support) development from outside of our company. To get it directly from Ryan is great bonus. To share it open source and make ProcessWire even better is of course superb. The better and more popular ProcessWire is, the stronger our development framework is. It would be great to see fundraising projects for module development. Building open source modules is fun, and I don't believe anyone hates the idea to make few bucks at the same time. But I think there are plenty of real money making opportunities coming now that ProcessWire is gaining more popularity: paid modules, paid profiles, site building, paid support, books, learning videos / tutorials, consulting... Currently PW has still relatively small audience, so I don't believe any module or book can get super high sales. But this is growing audience and very little competition. I would love to see more people trying to make money this way.1 point
-
Just wanted to mention some updates I was recently working on. 1. The Cheatsheet is now a ProcessWire Site (since couple months already). This allows for easy updating by team members. Also it allows for implementing stuff that wouldn't be easy with a static html. So all entries are now pages. This was very easy to setup and import the html data via a simple script. 2. Since we now got all the power of PW there, my idea was to create a API doc Site that would serve as a alternative extended sort of cheatsheet. Similar to php.net where you can see more details along with simple code examples and further information like what version introduced or if it's depreciated, related links to other API's. Also there's possibility to add comments. This opens great possibilities to give more information to you, add a "social" aspect, and at the same time also open it for indexing by search engines . You can see the current (not finished) version of the extended API doc here: http://cheatsheet.processwire.com/pages/built-in-methods-reference/pages-find-selector/ We are currently adding content and examples to the API's so this will take some time. Also there will be added some cross linking from the Cheatsheet to the extended docs when ready. Hope you like it. (edit: just realized that this was the 100th response in this thread! great coincidence)1 point
-
While I think Asana works very well, it's better with a team effort! Since I work alone, I have found Trello to work very well for me.1 point
-
1 point
-
Would something like this work? (written in browser, so might need tweaking). This should print all events sorted by date descending, but grouped by day and sorted by time ascending within the day. $allEvents = $pages->find("parent=/events/, sort=-date"); while($allEvents->count()) { $event = $allEvents->first(); $from = strtotime(date('Y-m-d 00:00', $event->getUnformatted('date'))); $to = strtotime("+1 day", $from); $events = $events->find("date>=$from, date<$to, sort=date"); echo "<h3>Events on " . date('F j, Y', $from) . "</h3>"; foreach($events as $event) { echo "<p><a href='$event->url'>$event->title</a> $event->date</p>"; $allEvents->remove($event); } }1 point
-
This hasn't been asked, but wanted to cover how the permissions and publish workflow work on the site. It has a very simple, though nice setup, where authors can submit new posts but can't edit already published posts, nor can they edit unpublished posts by other authors. It enables Mike to have full control over any content that gets published on the site, while still allowing easy submission and edits for the authors. Post workflow All of the authors have a role called "author" with page-edit permission. On the "post" template, the boxes for "edit" and "create" are checked for this "author" role. This site also makes use of the page-publish permission, which is an optional one in ProcessWire that you can add just by creating a new permission and naming it "page-publish". Once present, it modifies the behavior of the usual page-edit permission, so that one must also have page-publish in order to publish pages or edit already published pages. The "author" role does not have page-publish permission. As a result, authors on the site can submit posts but can't publish them. Nor can they edit already published posts. In this manner, Mike has final say on anything that gets posted to the site. Post ownership The default behavior in ProcessWire is that the Role settings control all access... meaning all users with role "author" would be able to do the same things, on the same pages. In this case, we don't want one author to be able to edit an unpublished/pending post created by another author. This was easily accomplished by adding a hook to /site/templates/admin.php: /** * Prevent users from being able to edit pages created by other users of the same role * * This basically enforces an 'owner' for pages * */ wire()->addHookAfter('Page::editable', function($event) { if(!$event->return) return; // already determined user has no access if(wire('user')->isSuperuser()) return; // superuser always allowed $page = $event->object; // if user that created the page is not the current user, don't give them access if($page->createdUser->id != wire('user')->id) $event->return = false; }); Planned workflow improvements Currently an author has to let Mike know "hey my article is ready to be published, can you take a look?". This is done by email, I'm assuming. An addition I'd like to make is to add a Page reference field called "publish_status" where the author can select from: DRAFT: This is a work in progress (default) PUBLISH: Ready for review and publishing CHANGE: Changes requested - see editor notes DELETE: Request deletion Beyond that, there is also an "editor_notes" text field that only appears in the admin. It's a place where Mike and the author can communicate, if necessary, about the publish status. This editor_notes field doesn't appear on the front-end of the site. All this can be done in ProcessWire just by creating a new field and adding these as selectable page references. That's easy enough, but I want to make it so that it notifies both Mike (the reviewer) and the author by email, every time there is a change in publish status or to the editor_notes. This will be done via another hook in the /site/templates/admin.php: wire()->addHookAfter('Page::saveReady', function($event) { // get the page about to be saved $page = $event->arguments(0); // if this isn't a post, don't continue if($page->template != 'post' || !$page->id) return; // if this post wasn't made by an "author" don't continue if(!$page->createdUser->hasRole('author')) return; $subject = ''; $message = ''; if($page->isChanged('publish_status') || $page->isChanged('editor_notes')) { // the publish status or editor notes have changed $subject = "CMSCritic post publish status"; $notes = $page->isChanged('editor_notes') ? "Notes: $page->editor_notes" : ""; $message = " Title: $page->title\n URL: $page->httpUrl\n Status: {$page->publish_status->title}\n $notes "; } else if($page->isChanged('status') && !$page->is(Page::statusUnpublished)) { // page was just published $subject = "CMSCritic post published"; $message = "The post $page->httpUrl has been published!"; } if($message) { $reviewer = wire('users')->get('mike'); $author = $page->createdUser; mail("$reviewer->email, $author->email", $subject, $message); $this->message("Email sent: $subject"); } }); Mike, if you are reading this, does this sound useful to you?1 point
-
@kyle: well written and easy to read, thanks for sharing! Two things I'd like to point out: You might want to add some random element to your activation hashes. MD5 is easy to spot and based on that information anyone mischievous enough could easily do things like automated account creation. Not that it would matter in most cases, but if a site using this was going to be in large-scale use then I'd be a bit worried about that. You're using custom methods to sanitize URLs, usernames, hashes etc. Take a look at $sanitizer -- it provides methods for sanitizing PW usernames, text (this should be a good fit for your hash) and even URLs. No need to reinvent the wheel1 point
-
Glad you guys like it, Pete did a phenomenal job and was great to work with. More modules to follow soon, standby!1 point
-
We just launched a new e-commerce website built off of ProcessWire. We worked off of Apeisa's shopping cart module as a base and were able to get the system integrated with Authorize.net's DPM for payments. We had a to do a lot of custom programming for this client as they needed sales tax, promo codes, and different shipping rates for different zip codes. I was delighted throughout the whole process with how much I was able to tailor the editing experience for the client as well as the visitor's experience on the page. The client had several last minute requirements which we would never have been able to implement in the time we had if we were using a different CMS and didn't have PW's API and custom field system. I would like at some point to release some of the new shopping cart code (shipping rates by zip code, sales tax, promo codes) to the rest of the community, but as it stands it's not modularized/generic enough and the code is in too many different pieces to make it practical. If I have time outside of work I will try to see if I can make it more distributable so that I can give back something to PW Special thanks to Apeisa for his input when we were getting started with this. http://www.harkenslandscapesupply.com/1 point
-
There's a setting for this in Process Users module (Admin > Modules > Users.) It allows you to choose exactly which fields you want to show in users list.1 point
-
Try using $session->authenticate() to do this. Check it out in wire/core/session.php Call it something like the code in line 209.1 point