Leaderboard
Popular Content
Showing content with the highest reputation on 04/02/2016 in all areas
-
Better late than never. I'm almost done with my WordPress vs. ProcessWire series. I have about ~8 videos left to make. I will be uploading all the videos to YouTube in a playlist. Need a couple more weeks to finish them off and add a little polish. Here are the videos in the series (not yet in the final order): Installation Pages Page Templates Custom Fields Custom Post Types Blog Documentation API Updates Client Help Plugins Forms Shortcodes Page Order Images Videos Themes Widgets Menus Global Settings and Options Page Caching Search Engine Optimization XML Sitemaps JSON Data Search Users and Roles Config File Multi-Language Data Migration Ecommerce Community Comments Revisions Admin Themes Command Line Interface Hosting Multisite Admin Section Performance Visual / WYSIWYG Editor Bootstrapping Admin Bar Composer Debugging Front-end Editing Page Builders Each video is about 3-10 minutes long and compares a feature in WordPress with the same or analogous feature ProcessWire quickly and concisely. For example, Shortcodes vs. HannaCode, Gravity Forms vs. FormBuilder, WP-CLI vs. Wireshell, WP Rocket vs. ProCache, WP's Menu Builder vs. Menu Builder, etc. Some are a little more in-depth than others. I do give WordPress a fair shake, try to remain objective and let ProcessWire's superior approach to features speak for itself. I will most likely be adding an intro video that explains the series as well with some background as to why I use ProcessWire instead of WordPress and the philosophical differences between the two. The goal is to get people, particularly advanced developers and web firms who know how to code and who are on the fence about switching to a new CMS, to quickly see all the analogous features that they are used to in WordPress done in ProcessWire. Hopefully they will get the warm and fuzzy feeling and explore our community further. If there are any topics you feel that I have missed, please let me know. Make sure the topic is specific enough to warrant a video of its own, as this series is a feature-to-feature comparison. Thanks12 points
-
This module provides a very simple interface to a set of named counters. You simply call a single function, next('name'), to pull the next value out of a counter - or to set it up if it does not yet exist. Next() takes a few extra parameters to allow you to increment by values other than 1 or to start at a certain number. This provides some similar functionality to the built-in page naming feature of PW, and to this module recently posted by Stikki but I think it offers a little more flexibility than either. Having said that, I do like the simplicity of Stikki's new auto-increment module. Module Availability Here is my module on Github. Here it is in the module repository. Example Usage Here's how this module can be used to title and name a new page by adding a couple of simple hooks to site/ready.php. This example applies to new pages using a template called 'invoice' that can be quick-added to the page tree. In order to get the following to work, you must edit the template that will be the parent of the 'invoice' template and setup the template for children to "invoice" and set the "Name Format for Children" field to something other than the default blank value (I use title as my value.) <?php /** * Function to recognise our special template. */ function isInvoiceTemplate($template) { return ($template == 'invoice'); } /** * Pre-load the page title for invoice pages with a unique value * which includes a counter component. */ $pages->addHookBefore("Pages::setupNew", function($event) { $page = $event->arguments(0); $is_invoice = isInvoiceTemplate($page->template); $no_inv_num = $page->title == ''; if ($is_invoice && $no_inv_num) { $counter_name = 'WR-' . date('Y'); $number = $this->modules->get('DatabaseCounters')->next($counter_name, 10, 5000); $page->title = $counter_name . '-' . sprintf("%06u", $number); } }); /** * Prevent ProcessPageEdit from forcing an edit of the name if we got here * through a quickAdd from ProcessPageAdd. We can do this because we * preset the title field in the Pages::setupNew hook. */ $pages->addHookAfter("ProcessPageEdit::loadPage", function($event) { $page = $event->return; $is_invoice = isInvoiceTemplate($page->template); $is_temp = $page->hasStatus(Page::statusTemp); if ($is_invoice && $is_temp) { $page->removeStatus(Page::statusTemp); $event->return = $page; } }); Note, the above code + module is one direct solution to the problem posted here by RyanJ. Version History 1.0.0 The initial release.5 points
-
Perfmon Debug Toolbar is a Processwire module used in performance monitoring and optimization. This module has been kicking around for some time, but I finally got around to publishing it. The user interface is heavilly influenced by django-debug-toolbar if anyone is familiar with that project. During install, $config->debug must be set to true for the toolbar to run, the module is not intended to be enabled on production. The primary goal of the module is to identify bottlenecks and help tune up code. More information is here: https://github.com/KeeneState/DebugPerfmon Please let me know if you have any difficulty installing or running it. It's intended to be run on a development instance, though it can exist in a dormant state in production. Collapsed presentation (top right of screen): Expanded Presentation:5 points
-
So a while ago I started a thread about using an existing processwire as the back end for a mobile app. There was some discussion about how viable it was, but i've been working with another developer and we've started to get somewhere. This iOS app https://appsto.re/gb/mtaH_.i uses http://www.dudmc.com/ as the back end. It's not perfect but we're pretty pleased so far.4 points
-
As promised, here's a link to my module that RyanJ's been helping to test out.3 points
-
This week we've got major upgrades to ProcessWire's selector engine, a great new version of Form Builder, and a few other core updates as well! https://processwire.com/blog/posts/processwire-3.0.13-selector-upgrades-and-new-form-builder-version/3 points
-
2 points
-
Also, every time if something weird is going on, having a look into the AdminDebugTools Hook-Section is useful (I believe you can call it from within TracyDebug too). Here you may spot if multiple / different modules hook into the same methods, or into "nearly" the same methods, what always has potential to interfere.2 points
-
Horst, thank you for putting me one right track. Actually the difference was in the templates, but I couldn't see it there. There is no 'UTF-8' switch or anything like that in the templates area. I then went through my modules and found a suspect: it is called PageAutoName , and after turning it off everything was ok. Maybe it happened because this module was not approved for my actual version (3.0.12) or it just can't cope with the extended page name. Anyhow, this situation shows the crux between being 'lazy' and using these comfortable helpers (modules) and somehow losing control over the process (who is doing what). In that context it would be helpful to see on the template view which modules are influencing the process of this template. Right now you have to go through all modules and look if they are set active for which template ( or is there another way finding that out?). Thanks all for the patience!2 points
-
Hello everyone, I always wanted to try out an ajax autocomplete search function, but never knew where to start. Of course there is the Ajax Page Search module by soma, but it seems that it was build around the basic site profile. In my case I wanted something more custom and I discovered in this thread the jQuery Plugin Typeahead by RunningCoder, which seemed to be nice. After many hours figuring out, how to combine this Plugin with ProcessWire, I finally got it implemented and want to share my solution with anyone, who also struggles with this topic. 1. Set-Up Typeahead Download the Typeahead-Plugin from the website (I prefer via Bower) and include the following scripts and stylesheets in your templates: <html> <head> ... <!-- Optional CSS --> <link rel="stylesheet" href="/vendor/jquery-typeahead/dist/jquery.typeahead.min.css"> <!-- Required JavaScript --> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> <script src="/vendor/jquery-typeahead/dist/jquery.typeahead.min.js"></script> ... </head> As next step we need the JSON data. 2. Install Pages to JSON To get the necessary data of all pages as JSON, I use the module Pages to JSON, which provides an easy way to output pages as JSON objects. Of course you can achieve this without this module, but I am not very experienced with JSON, so this module was really helpful. After you downloaded and installed the module, you can configure in the module settings page, which fields you want to output. You can select between own and system fields. For my purpose I selected only title and url to be outputted. 3. Output JSON Now, that we have the module configured, we have to output our search suggestions as JSON. I did it in my template file search.php like this: <?php namespace ProcessWire; // Check if ajax request if($config->ajax) { $results = $pages->find("has_parent!=2"); // Find all published pages and save as $results header("Content-type: application/json"); // Set header to JSON echo $results->toJSON(); // Output the results as JSON via the toJSON function } else { // Your own front-end template } To sum up, we search the pages we want as search suggestions and save them in a variable. Then we output them with the toJSON-Function by the Pages to JSON-Module. All of this happens in a Ajax-Request, that is the reason why we check first, if the page is called via an Ajax request. 4. Insert Form We can now embed the HTML form anywhere you want. Either in an header-include or a specific template. Also you can use your own classes, for this example I used the Typeahead-demo-mark-up and extended it a little. <form id="searchform" method="get" action="<?= $pages->get("template=search")->url ?>"> <div class="typeahead__container"> <div class="typeahead__field"> <span class="typeahead__query"> <input id="q" name="q" type="search" placeholder="Search" autocomplete="off"> </span> <span class="typeahead__button"> <button type="submit"> <span class="typeahead__search-icon"></span> </button> </span> </div> </div> </form> The action-attribute in the form-tag is the url of your search-site. This attribute is of course necessary to know where the form redirects you and where the JSON data is located. 5. Initialize Typeahead As last step we have to initialize the Typeahead-plugin jQuery like this: $(document).ready(function() { var actionURL = $('#searchform').attr('action'); // Save form action url in variable $.typeahead({ input: '#q', hint: true, display: ["title"], // Search objects by the title-key source: { url: actionURL // Ajax request to get JSON from the action url }, callback: { // Redirect to url after clicking or pressing enter onClickAfter: function (node, a, item, event) { window.location.href = item.url; // Set window location to site url } } }); }); We save the action url of the form in a variable, then we initialize Typeahead by selecting the input-field inside the form. As the source we can pass the action url and I included the callback, to link the search results with the site urls. Now you should have a nice ajax autocomplete search form, which of course you can further style and configure. I hope I didn't forget anything, but if so, please let me know. Regards, Andreas1 point
-
A couple of requests to make working with templates in Admin more streamlined: 1. Display the "Label" field in the "New Template" screen - I always like to label my templates and currently this requires you to re-open the template you have just created. Also, I'd rather have the template screen remain open after adding a template rather than be sent back to the Templates overview. These changes would make the "New Template" process more consistent with the "New Field" process. But of course the likely reason for no Label field and the closing of the template screen is because it's actually "New Templates" plural not "New Template" singular. Myself, I've never felt the need to add multiple templates at once but I expect others do. Maybe "New Template" and "New Templates" could be separate commands? 2. When duplicating a template (Add New Templates > Duplicate fields used by another template) it would be nice if field overrides (widths, descriptions, etc) were included in the new template(s). It can be quite time-consuming to set these up, and if you are duplicating fields of an existing template I think you also want to duplicate the overrides more often than not.1 point
-
Hi @horst - excellent answer! Many thanks indeed I am using PW3 and taking advantage of all the latest goodness! Hope you're having a great weekend and I appreciate your very quick response. Cheers!1 point
-
Hi @Gazley, you are speaking of the new core (PW 3) ImageSizerEngineIMagick.module? (Better do not use the old IMagick Sizer module, or, if so, do you stuck with PW 2.7 ?) But to your question: The hirarchy of options is this way, lowest to highest: (higher ones overwrite lower ones) module default (is only there if all others are missing) global setting in wire/config.php (is the distribution default) global setting in site/config.php (can be set to overwrite the distribution default per site) setting in array options, passed to pageimage (overwrites all others) with methods width, height, size If the module has a default of 80, the wire/config.php has 90, the result is 90. If you pass an option with 75 to size(), the resulting quality is 75. Pia is only a wrapper around pageimage, so any option passed to Pia (pageimage), overwrite all other (hirarchically previous) options.1 point
-
To extend the above example to hide the name, template and parent fields on the settings page of invoices, you can add the following to the ready.php snippet in the above post. /** * Work out if the template's settings should be tweaked to hide things that should be fixed... */ function shouldHideTemplateSettings() { // Super users retain super-setting-edit powers if (wire('user')->isSuperUser()) { return false; } // Are we even editing a page? if (wire('page')->process != 'ProcessPageEdit') { return false; } $id = (int) wire('input')->get('id'); if (!$id) { return false; } $editedPage = wire('pages')->get($id); if ($editedPage->template->flags & Template::flagSystem) { return false; } if (!isInvoiceTemplate($editedPage->template->name)) { return false; } return true; } /** * Hide some fields from the invoice settings page from non-super-users. * * There's not much point allowing edits to the name field, so we want it immutable (at least) and probably totally * hidden (better.) * * We don't want invoices being moved from their parent, so we hide the parent field. * We don't allow them to use a different template, so we hide the template field. * */ if (shouldHideTemplateSettings()) { $pages->addHookAfter("ProcessPageEdit::buildFormSettings", function($event) { $wrapper = $event->return; // To show the name field but make it immutable $wrapper->_pw_page_name->collapsed = Inputfield::collapsedNoLocked; $wrapper->_pw_page_name->description = ''; // Alternatively, to hide the name field do uncomment the following and comment out the 2 lines above //$wrapper->_pw_page_name->collapsed = Inputfield::collapsedHidden; // Hide the template changer, invoices can only use the invoice template $wrapper->template->collapsed = Inputfield::collapsedHidden; // Hide the parent page, as it is fixed in our page structure $wrapper->parent_id->collapsed = Inputfield::collapsedHidden; }); }1 point
-
Hi Ben, Just wanted to say thank-you for this module. I'm trying it out now and am really liking it!1 point
-
There are some points you're missing. ProcessWire does not (really) deny access to php files in the templates folder, it just denies direct access to those php files, because they would most likely not work correctly. You can however use any of those php files in that folder if you have a template using it as well as a page using the template. Just use the page's url in your js file and the linked php file will be called. Only by accessing a page instead of the file directly ProcessWire is bootstrapped before the php (template) file is executed and all your api variables are available. But you could also use a custom php file, without the need to have a template and page set up. You can also manually have ProcessWire bootstrapped by including it like it's described here: https://processwire.com/api/include/1 point
-
With Adrian's TracyDebugger module, we get a list of loaded modules in the Debug Mode panel. Maybe this is the tool you are looking for?1 point
-
It seems that opengraph tags require "property" instead of "name" in tags: http://ogp.me/ Here is a quick fix (around line 330, added dynamic $attributeName): // add "render" $rendered = ''; foreach($pageData as $name => $content) { // set "property" as meta attribute name instead of "name" if it's an opengraph tag $attributeName = strpos($name, 'og:') !== false ? 'property' : 'name'; switch($name) { case 'custom': break; case 'title': if($this->titleFormat == '') break; $rendered .= '<title>'.$this->parseTitle($page, $content).'</title>'.PHP_EOL; break; case 'canonical': $rendered .= '<link rel="canonical" href="'.$content.'" />'.PHP_EOL; break; default: $rendered .= '<meta ' . $attributeName . '="'.$name.'" content="'.$content.'" />'.PHP_EOL; break; } } Also, it's a good practice to add og:image:width and og:image:height, this ensures the image is loaded on first facebook share (otherwise it's empty). Maybe the module could automatically add these too.1 point
-
You mean the Schedule Pages module? That's actually possible. From a quick glimpse, it hooks before Pages::save and, if a publish_from date is set, tries to clear that and calls "$page->save('publish_from');". This line should probably only be executed if $page->isNew() returns false.1 point
-
1 point
-
I've PM'd my module over to Ryan for testing. Let's see what comes of it over the next couple of days. If it works out we'll post updates here.1 point
-
You guys have to do it through Google translate. I'll give you something straight from the target audience of this update. ПроцессВаир теперь поддерживает кириллические урлы! С сегодняшнего дня сайты в зоне .рф можно полноценно создавать на этой замечательной системе. Благодарим Райана за заботу. Ура, товарищи!1 point
-
This improvement could come handy, for me it comes up regularly. API method to check if image is a default image: would return true if selecting a page instead uploading an image, using the admin "Default value (when empty)" field (eg. "isDefaultValue" or "isPlaceholder"). Currently I have to check for a file name ("no-image.png"), obviously not the best way.1 point
-
I am sure Wanze will be able to offer up a solution to get the filesize from the path. I just wanted to chime in with a nice function for converting to human readable filesizes: http://jeffreysambells.com/2012/10/25/human-readable-filesize-php function human_filesize($bytes, $decimals = 2) { $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); $factor = floor((strlen($bytes) - 1) / 3); return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor]; }1 point