Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/23/2017 in all areas

  1. This week we've got new versions of the Uikit 3 admin theme, a new version of ProCache with SCSS and LESS support, plus a brand new module that provides user login, new user registration and a user profile editor, all for the front-end of your site. And of course, a new core dev version too (3.0.76)! https://processwire.com/blog/posts/pw-3.0.76-plus-login-register/
    9 points
  2. Nearly all of my projects are intranet solutions or limited-audience web applications rather than web sites, so my top requested features differ a bit: Sufficiently fine-grained permission system (check) Drag & drop support for files (check) Multilanguage support (check) Approval process (currently testing that with ProDrafts ) Interfaces to third party software (Active Directory, SAP, time keeping software, DMS etc., check, all of those easy to integrate with a few lines of code ) Sign in using credentials from above software (check, just a few lines...) Advanced search that supports (Word, Excel, PDF...) files and honors permissions (done with UserGroups and OpenSearchServer)
    7 points
  3. Wow, super update this week! The SCSS compilation feature in ProCache sounds great. Currently I have a roll-my-own solution using scssphp - does the new ProCache feature use scssphp or something different? The front-end users module is awesome news - it's one of those few missing pieces that PW has been really needing. Beginners especially will benefit from this, and because of the security considerations that come with a login system it's great to have a solution from PW's creator. I was expecting that such a module would be a "Pro" release, so big thanks for making this a free module! Can't wait to try it.
    6 points
  4. I was reiterating the suggestion from PHP The Right Way, that I found out just yesterday. Which got me curious, and did my own tests. RAM usage doesn't change, but on CPU time it has some effect. // 8000 pages with title and body fields $pp = $pages('template=basic, parent=1384'); $out = ''; foreach($pp as $p) { $t = $p->title . microtime(); $b = $p->body . mt_rand(0, 1e5); $out .= $t . $b; } echo strlen($out); // 18384.08ms, 25.00 MB // 8000 pages with title and body fields $pp = $pages('template=basic, parent=1384'); $out = ''; foreach($pp as $p) { $out .= $p->title . microtime(); $out .= $p->body . mt_rand(0, 1e5); } echo strlen($out); // 17617.05ms, 25.00MB $out = ''; foreach($pages('template=basic, parent=1384') as $p) { $out .= $p->title . microtime(); $out .= $p->body . mt_rand(0, 1e5); } echo strlen($out); // 17927.9ms, 25.00MB Verdict: Don't believe everything you read on the internet. Do your own tests.
    4 points
  5. Client: "What's a filter? Should I add one? Why are there all these dropdowns? What's a num_children? I've forgotten my modified_users_id - can you email it to me? What's a bookmark? I have a bookmark for Google - is it like that? I don't understand what I do on the columns tab. My brain hurts. Why did you make this so confusing? etc, etc, etc" But seriously, it's just a permission so you have the option to show Lister to a role or not show it to a role. It's just to give flexibility.
    4 points
  6. Just in case its useful for anyone, this is my function for creating a folder list with public links to files: <?php namespace ProcessWire; use Kunnu\Dropbox\Dropbox; use Kunnu\Dropbox\DropboxApp; use Kunnu\Dropbox\DropboxFile; $drop = $modules->get('DropboxAPI'); //Configure Dropbox Application $app = new DropboxApp($drop->app_key, $drop->app_secret, $drop->authorization_code); //Configure Dropbox service $dropbox = new Dropbox($app); // get folder from user $folder_path = ""; $folder_path = $user->folder; // get items from dropbox folder $listFolderContents = $dropbox->listFolder($folder_path); //root folder is the folder you nominated in the Dropbox App config. Refer doco $items = $listFolderContents->getItems(); function listItems($items, $dropbox, $depth = 0){ $out = "<ul class='depth-{$depth}'>"; foreach ($items as $item){ // get file name $name = $item->getName(); // getPathLower $path = $item->getpathLower(); $thumbPath = "no thumb"; $thumbHasExt = strpos($path, '.'); // file if($thumbHasExt && $path){ $file = $dropbox->getTemporaryLink($path); $link = $file->getLink(); $ext = substr($path, $thumbHasExt+1); // fontawesome file name icons $icon = "fa-file-o"; switch ($ext) { case 'png': case 'jpg': case 'gif': case 'psd': case 'tiff': $icon = 'fa-file-image-o'; break; case 'pdf': $icon = 'fa-file-pdf-o'; break; case 'mp3': case 'wav': $icon = 'fa-file-audio-o'; break; case 'mov': case 'mp4': case 'm4a': $icon = 'fa-file-video-o'; break; case 'doc': case 'docx': $icon = 'fa-file-word-o'; break; case 'xls': case 'xlsx': $icon = 'fa-file-excel-o'; break; case 'ppt': case 'pptx': $icon = 'fa-file-powerpoint-o'; break; case 'zip': case 'rar': $icon = 'fa-file-archive-o'; break; } $out .= "<li><span class='{$icon} fa'></span><a title='click to download' href='{$link}'>{$name} {$ext}</a></li>"; // folder }else{ ++$depth; $out .= "<li><span class='fa-folder-open-o fa'></span>{$name}"; $listSubFolderContents = $dropbox->listFolder($path); $items = $listSubFolderContents->getItems(); // get list of files in subfolder $out .= listItems($items, $dropbox, $depth); $out .= "</li>"; } } $out .= "</ul>"; return $out; } // get depth 0 folder items $out = listItems($items, $dropbox, $depth);
    3 points
  7. From the top of my head: I've built a small schema for OSS that has the following additional fields: PW language name groups (multivalued) page id type indicator field for file or page to limit results to one of those if required an additional file classification field to search for special documents (e.g. process instructions, sales catalogs...) In a save handler, I call my search update routine that: removes all entries in OSS for the current page id includes the search engine update logic for the current template that in turn: extracts the content extracts information on all files that should be in the search adds a search entry through OSS' REST API for each of those for each language with page id, language, type and all permitted groups My search routine then only needs to pass the current user's groups (from @apeisa's essential UserGroups module) and optionally the language to the search API as facet filters to get permission-filtered results. I'm in the process of moving the actual update action to background batch jobs since the number of files and their sizes are constantly growing, slowing down page editing. This will have the nice added effect that I can run the updating logic on one or more different servers by sharing the file system between them. And, of course, there's a script for worst cases that runs through all pages and builds the search index from scratch.
    3 points
  8. v1.5.8 is uploaded so you can try the new "CKEditor customization" feature where you can set CKEditor toolbar buttons and other properties. I think it's a pretty powerful feature with only a few lines of code, thanks to PW and using INI fomat in the configuration textarea. For details, see the bottom of CKEaddons in the docs. Plus I've reorganized the module assets including the compile/minify process, hopefully without any issues.
    3 points
  9. Wonderful to see a native Login script. I'd say it's in the top 5 queries I have when I show PW to another designer/developer.
    3 points
  10. A fantastic upgrade to ProcessWire's core capabilities. Thanks for making our lives easier.
    3 points
  11. Hello @Jon E However, you use $page->children which is the reference to "children" in the context of the Page Tree. When dealing with page reference fields of templates, you need to reference the page reference field by its name, something like $page->my_tags for example: <?php namespace ProcessWire; foreach($page->selectedthumbs as $selectedthumb) { echo "<tr><th><a href='{$selectedthumb->url}'>{$selectedthumb->title}</a></th><th>{$selectedthumb->contributors}</th></</tr>"; } BTW: You do not need the if clause in this case, because if your PageArray is empty, the loop will not run in the first place. You left out the closing tag of <a> element If you are getting Page IDs then you are probably on the right track as that means you have a PageArray there. In ProcessWire the __toString() magic method renders the IDs when you access them as if they were strings. Meaning when you see them, you need to loop through the variable in question instead of echoing it. https://github.com/processwire/processwire/blob/57b297fd1d828961b20ef29782012f75957d6886/wire/core/PageArray.php#L579 Hope this helps. If not, please provide more code and info about the context you are having trouble with.
    2 points
  12. After Ryan's post yesterday re. the new Login Module I was thinking how great it is to finally have this in the core. I get asked a little about Login Modules when I show PW to people. Just out of curiosity, what type of features are you asked about when showing PW to your peers? Here's the top 5 FAQs I'm usually asked. Does it have ... user login/out and membership management have good SEO support image cropping incl media management versions or drafts capability with approval process e commerce And then sometimes ... page builder type fields (Matrix I guess) Multilingual support Taxonomy / tags / categorisation Blogging Web forms What kind of stuff do you get asked about?
    2 points
  13. Nice one. How about using InputfieldAceExtended for the configuration textarea if it is installed? if($this->modules->isInstalled('InputfieldAceExtended')) { $f = $this->modules->get('InputfieldAceExtended'); $f->mode = 'ini'; $f->modes = array('ini'); $f->theme = 'twilight'; } else { $f = $this->modules->get('InputfieldTextarea'); } $f->attr('name', 'CKEaddons_toolbar'); //...
    2 points
  14. Can you tell more about that?
    2 points
  15. Hello @Missariella, however, I am using the latest dev version (3.0.76) and its working. First of all I recommend you to create a global translation piece of code. Put it somewhere in a file that is loaded everytime (fe. a function.php), so the translation code will be availiable everywhere. You can put it also in the template file where you want to output the select options, but loading it in general makes more sense in this case, because you can use it in other templates too. Here is the code: //get labels, title, values and descriptions in different languages if ($user->language->name != 'default') { $title = "title{$user->language}"; $value = "value{$user->language}"; $label = "label{$user->language}"; $description = "description{$user->language}"; $notes = "notes{$user->language}"; } else { $title = 'title'; $value = 'value'; $label = 'label'; $description = 'description'; $notes = 'notes'; } This little code snippet makes titles, values, labels, descriptions and notes available in all languages by only calling "$title" instead of "title" (or "$label" instead of "label" and so on...). So it makes your life much easier Afterwards creating a multilanguage select can be done like this: $options = $fieldtypes->get('FieldtypeOptions')->getOptions($fields->get('YOURFIELDNAME')); foreach ($options as $value) { echo $value->$title; echo $value->$label; echo $value->$description; } This outputs title, label and description in the user language. This is the code that I am using on my projects without any problems.
    2 points
  16. I opened a GitHub issue myself: https://github.com/processwire/processwire-issues/issues/383
    2 points
  17. Hello, this module can publish content of a Processwire page on a Facebook page, triggered by saving the Processwire page. To set it up, configure the module with a Facebook app ID, secret and a Page ID. Following is additional configuration on Facebook for developers: Minimum Required Facebook App configuration: on Settings -> Basics, provide the App Domains, provide the Site URL, on Settings -> Advanced, set the API version (has been tested up to v3.3), add Product: Facebook Login, on Facebook Login -> Settings, set Client OAuth Login: Yes, set Web OAuth Login: Yes, set Enforce HTTPS: Yes, add "https://www.example.com/processwire/page/" to field Valid OAuth Redirect URIs. This module is configurable as follows: Templates: posts can take place only for pages with the defined templates. On/Off switch: specify a checkbox field that will not allow the post if checked. Specify a message and/or an image for the post. Usage edit the desired PW page and save; it will post right after the initial Facebook log in and permission granting. After that, an access token is kept. Download PW module directory: http://modules.processwire.com/modules/auto-fb-post/ Github: https://github.com/kastrind/AutoFbPost Note: Facebook SDK for PHP is utilized.
    1 point
  18. Cool. But I do think it makes sense for utilities like CodeMirror or Ace to exist as separate inputfield modules so that they can be used elsewhere in Page Edit, other modules, etc, rather that duplicated within every module that uses them. Things like this are not really dependencies (a plain textarea works fine without them) but more a progressive enhancement.
    1 point
  19. You can upload your site files after zip, via scp also scp local_site.zip runcloud@server-ip-address:webapps/your-web-app-path/ If you read documentation, database section you can see the answer : https://runcloud.io/docs/server/database.html#rc-docs-scroll You need to add 3306/tcp port, like here. after add port to your firewall settings, you can connect your database with your server ip from anywhere. You can use Sequel Pro app for connect to your database. After you done with database, don't forget to remove 3306/tcp port!
    1 point
  20. Is there a way to disable email validation on the Login/Register/Profile plugin when users register to the website from the frontend?
    1 point
  21. That is a perfect response! Funny too! I definitely wasn't thinking along those lines when I saw the permission, but it makes much more sense now. Haha. Thank you Robin S!
    1 point
  22. Think I've sorted GitHub. Let me know if anyone has probs getting the module from there.
    1 point
  23. I just liked the theme Thanks for your comment. Keep in mind that this is a simple setup and I think still needs polishment. It was release like a year ago and many new Processwire goodies could become handy for a blog
    1 point
  24. It's a mixed approach. I use page-per-file to inline our most important process documentation PDFs enhanced with keywords, tags and meta data, most with all the niceties of built-in multi-language support. Our construction pages make heavy use of my MediaLibrary module for images and shared reference docs. A lot of department docs are added to simple file fields, and, to round everything off, version critical files (like technical drawings) stay on our network shares but our editors can easily add links to those through custom built CKEditor extensions. There's a bit of tag and save handler magic as well as prepend scripting going on so these files (and ones resting in the DMS) are available through URLs (either segments or get params), permissions are honored and they can be found in the search.
    1 point
  25. WORKED!!!!! WHHHHOOOOPPPP. Thank you! Obvioulsy a bit of a n00b still for "proper" dev stuff. any good articles about composer best practises? Thanks
    1 point
  26. @benbyf are you using composer? Or manually downloading the packages? vendor directory and autoload.php is created when you require a package with composer.
    1 point
  27. Why isn't it WordPress?
    1 point
  28. For completeness' sake, even though I agree that using a field that is limited in range may not be the best idea, here's how it should work without abusing ids: // Retrieve possible options through the field's typ $field = $fields->get("progress_status"); $progress_options = $field->type->getOptions($field); // Find the correct SelectableOption object by its desired value and assign it $page->progress_status = $progress_options->get("value=" . ($page->progress_status->value + 1)); Each SelectableOption object is made up of a (random and unique) id, a value (that's what you search for and assign) and a label (what the user sees in the select/radio/checkbox input).
    1 point
  29. Why not use closures? function print_foo() use($foo) { // to be able to change $foo use get it by reference &$foo instead print_r($foo); } One distinction is that with closures $foo will have the value at the moment of function creation, whereas global $foo will have the value of $foo at the time of execution. Often this doesn't matter, but you should be aware. Also with closures you can reference variables from parent scope. To access even higher scopes, you'll have to use globals. https://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and
    1 point
  30. Why do you assume it isn't capable of different languages? The source code contains pretty much translatable strings like that: _('You have logged out') – the underscore indicates that it is translatable. What's missing now is the translation itself – feel free to chime in! Here is all you need
    1 point
  31. Not sure why you are using an Options field for this. I think you want an integer field named "number_of_saves" or whatever. Then you increment the number with each save originating from the front-end.
    1 point
  32. It's SO SO AWESOME! Million thanks, Ryan and Michael!
    1 point
  33. Had to look more at it again. No there's no such built in option. But there's some ways to do it. The first argument not only works with a root page but also with a PageArray. So you could do build a PageArray, add children of root, then prepend the home page to it and send that to Aligator. All you need to make sure you don't render level2 of home page which would render your menu again if home is your root. Got it? $menuPages = new PageArray(); $home = $pages->get("/"); $menuPages->add($home->children()); $menuPages->prepend($home); $content .= $modules->Aligator->render($menuPages, array( array( // level1 "selector" => "" ), array( // level2 : don't render the children of "home" "selector" => "parent!=1" ) ), 3); Or a more straight forward version is to use the wrapperOpen and add it manually. $homeUrl = $pages->get(1)->url; $nav = $modules->Aligator->render($pages->get(1), array( array( // level1 "selector" => "", "callback" => function($item, $level) use($homeUrl){ return array( "wrapperOpen" => "<ul><li><a href='$homeUrl'>Home</a></li>", ); } ) ), 3); The first last class thingy is not something I really ever use, but if it works for your navigation then it's ok to do it that way. It's just you would be careful if there's lots of pages as siblings. You'd also want to use the same selector you use for the level. Otherwise it would not work as the last sibling might be not rendered as by the selector.
    1 point
  34. try this one. I forgot to add ->type, when you add it both methods should work.
    1 point
  35. This seems to work $implements = wireClassImplements($field->type); $isMulti = in_array('FieldtypeLanguageInterface', $implements); // OR $isMulti = $field->type instanceof FieldtypeLanguageInterface; Adapting to your code: $data = []; foreach ($page->template->fieldgroup as $field) { // check if field is multi language if ($field->type instanceof FieldtypeLanguageInterface) { continue; } $data[] = $field; } return $data;
    1 point
  36. Do you have any images related modules or custom code? What PW version are you on?
    1 point
  37. @SarbjitGrewal The code looks to be from an ASP template. This is a forum for a PHP based CMS called ProcessWire. Are you sure you're at the right place? Edit: Now it's from a Genesis based WordPress theme
    1 point
  38. Cloudinary.com seems to offer everything you need and some more. You can get it to fetch images from your server on the fly and serve the right size image to visitors device without uploading images beforehand. Free tier is quite generous, too. https://cloudinary.com/features
    1 point
  39. That error from the Repeater module looks like the same thing I raised a GitHub issue for recently, so there's a good chance it relates to PW's caching of module data rather than Recurme specifically. Ryan has pushed a fix for the issue to the dev branch.
    1 point
  40. nothing fancy here. you see it's not polished and some hardcoded values... the javascript to handle the clicks: $(document).on('click', '.ckesnippet', function() { // find correct ckeditor instance $field = $(this).closest('li.Inputfield'); var id = $field.attr('id'); var ckename = id.replace('wrap_',''); var cke = CKEDITOR.instances[ckename]; var data = cke.getData(); cke.setData(data + $(this).data('snippet')); return false; }); and the hook to modify the field: $this->addHookBefore('InputfieldTextarea::render', $this, function($event) { $field = $event->object; if($field->name == 'rockinvoice_suffix') { $del = ''; foreach($this->wire->pages->get(38967)->texttemplates as $item) { $field->entityEncodeText = false; $field->description .= $del . '<a href="#" class="ckesnippet" data-snippet="' . str_replace(PHP_EOL, '', $item->body) . '">' . $item->title . '</a>'; $del = ' | '; } } elseif($field->name == 'rockinvoice_prefix') { $del = ''; foreach($this->wire->pages->get(38967)->texttemplates_greeting as $item) { $field->entityEncodeText = false; $field->description .= $del . '<a href="#" class="ckesnippet" data-snippet="' . str_replace(PHP_EOL, '', $item->body) . '">' . $item->title . '</a>'; $del = ' | '; } } $this->wire->modules->get('RockTools')->loadAsset('ckesnippets.js', 'HrDiamonds'); }); and a repeater to setup the snippets:
    1 point
  41. I am actually wondering if you might be better off not relying on ajax calls for each filter step. Have you considered storing all the details of all trees in a wireCache'd JSON object that you load up when the page originally loads and then filter through that in memory? I have done this before - I have 3MB of data in JSON which is cached, I make sure that data is transferred compressed (so it's only a couple of hundred KBs). The initially page load takes a couple of seconds, but after that, the filtering is instant. I think so long as you know that the data will not expand to an outrageous size, this might be a good approach. PS - Great looking site!
    1 point
  42. Definitely with @abdus on this one. PHP7 is noticeably faster than 5.6, and PW has no problems (that I'm aware of?) running under 7. If it is available, do it (taking the usual precautions, obvs). Also, there might be optimisations you could make to your selectors and there are probably mysterious optimisations you may be able to make to your mySQL setup, depending on how much control you have within your hosting. First of those you will probably get help with here, if you are able to share some code, second is down to black magic, voodoo and selling the soul of your firstborn. Or hiring an expert. All of that having been said, it's a very good looking website, and it works well - initial loading doesn't feel slow, just the filtering isn't instant. <edit>Man, 3 more replies while I write this one.</edit>
    1 point
  43. Hello, this module has been updated and it is now compatible with Graph API version 2.10. Parameters 'description' and 'name' are not supported by the new Graph API version. Therefore, fields for description and name cannot be provided anymore.
    1 point
  44. Well, considering the numbers, it's actually not a big surprise... bottom of https://wpisnotwp.com/ And like with most things, people who have never seen / used anything else, they can't even imagine that there's so many other options out there. Another reason is perhaps that those people in charge of choosing a CMS are hardly ever the people who have to use the system. The people who have to use a CMS on a daily basis are almost never asked about their opinion. Mostly, it's just a tiny part of their job, which they loathe. It's probably dull copy-and-paste-from-Word, 9 times out of 10.
    1 point
  45. Hello, We have all our clients on ProcessWire. Even EIZO, a huge monitor manufacturer. Statistics won't make them switch, or any other thing. The only person that can make them switch is you. So what does the client really want? Just to update their website? That can be done faster and easier with ProcessWire. This is how I usually sell ProcessWire in.
    1 point
  46. Remove the link and it should kick in again. Needs to just be plain text.
    1 point
  47. Thanks for your help! It was another error I made. It was the value of $config->userAuthSalt that I did not copy over from your config.php.
    1 point
  48. Doh... Solved my own problem.... Changed this... foreach($page->comments as $comment) To this... foreach($comments as $comment) Sorry for diverting you here... but thanks for looking! Here is what I have ended up with... // DISPLAY PAGINATED COMMENTS $limit = 10; // comments to display per page $start = ($input->pageNum-1) * $limit; $selector = "page=$page, sort=-created, start=$start, limit=" . ($limit+1); // find the comments. replace "comments" with the name of your comments field $comments = FieldtypeComments::findComments("comments", $selector); // output the comments foreach($comments as $comment) { if($comment->status < 1) continue; // skip unapproved or spam comments $cite = htmlentities($comment->cite); // make sure output is entity encoded $text = htmlentities($comment->text); $date = date('m/d/y g:ia', $comment->created); // format the date echo "<p>Posted by $cite on $date<br />$text</p>"; } // output the pagination links if($input->pageNum > 1) echo "<a href='./page" . ($input->pageNum-1) . "'>Back</a> "; if(count($comments) > $limit) echo "<a href='./page" . ($input->pageNum+1) . "'>Next</a>"; Thanks guys
    1 point
  49. See this Comments Fieldtype documentation page sections on customizing output and styling output. While it makes it easier, you don't actually have to use the built in methods for rendering the comments list or form. You can create your own markup entirely if preferred. However, I do think it would be worthwhile to copy or extend ProcessWire's /wire/modules/Fieldtype/FieldtypeComments/CommentForm.php file to your own class (MyCommentForm) in /site/templates/. When you want to render your form, you would do this: include("./MyCommentForm.php"); $form = new MyCommentForm($page, $page->comments); echo $form->render();
    1 point
  50. You might want to check out the blog profile, which uses "next/prev" for comments pagination: http://processwire.com/blogtest/comments/ Also, the current version of ProcessWire does include the ability to paginate comments, though it's not particularly automated yet. See the FieldtypeComments::findComments function. While not the prettiest bit of API code, you can use it like this: $limit = 10; // comments to display per page $start = ($input->pageNum-1) * $limit; $selector = "page=$page, sort=-created, start=$start, limit=" . ($limit+1); // find the comments. replace "comments" with the name of your comments field $comments = FieldtypeComments::findComments("comments", $selector); // output the comments echo $comments->render(); // output the pagination links if($input->pageNum > 1) echo "<a href='./page" . ($input->pageNum-1) . "'>Back</a> "; if(count($comments) > $limit) echo "<a href='./page" . ($input->pageNum+1) . "'>Next</a>";
    1 point
×
×
  • Create New...