Leaderboard
Popular Content
Showing content with the highest reputation on 12/01/2016 in all areas
-
One of the biggest projects I've done yet! ProcessWire has been such a god-send so far, and it continues giving. This is an estate agents powered by Vebra in real-time, which ProcessWire imports all the data from and stores as pages, allowing us to use ProcessWires amazing built in API functions. ProcessWire is really perfect for any project big or small. http://www.spencersestateagents.co.uk/ The team here at Peter & Paul really love ProcessWire and so do our clients!5 points
-
SeaVuel | Hotel CMS / template : http://seavuel.com/ | http://demo.seavuel.com/ Whose handiwork is this? It looks ryan-esque to me5 points
-
Hi everyone, Here's a new module that I have been meaning to build for a long time. http://modules.processwire.com/modules/process-admin-actions/ https://github.com/adrianbj/ProcessAdminActions What does it do? Do you have a bunch of admin snippets laying around, or do you recreate from them from scratch every time you need them, or do you try to find where you saw them in the forums, or on the ProcessWire Recipes site? Admin Actions lets you quickly create actions in the admin that you can use over and over and even make available to your site editors (permissions for each action are assigned to roles separately so you have full control over who has access to which actions). Included Actions It comes bundled with several actions and I will be adding more over time (and hopefully I'll get some PRs from you guys too). You can browse and sort and if you have @tpr's Admin on Steroid's datatables filter feature, you can even filter based on the content of all columns. The headliner action included with the module is: PageTable To RepeaterMatrix which fully converts an existing (and populated) PageTable field to either a Repeater or RepeaterMatrix field. This is a huge timesaver if you have an existing site that makes heavy use of PageTable fields and you would like to give the clients the improved interface of RepeaterMatrix. Copy Content To Other Field This action copies the content from one field to another field on all pages that use the selected template. Copy Field Content To Other Page Copies the content from a field on one page to the same field on another page. Copy Repeater Items To Other Page Add the items from a Repeater field on one page to the same field on another page. Copy Table Field Rows To Other Page Add the rows from a Table field on one page to the same field on another page. Create Users Batcher Allows you to batch create users. This module requires the Email New User module and it should be configured to generate a password automatically. Delete Unused Fields Deletes fields that are not used by any templates. Delete Unused Templates Deletes templates that are not used by any pages. Email Batcher Lets you email multiple addresses at once. Field Set Or Search And Replace Set field values, or search and replace text in field values from a filtered selection of pages and fields. FTP Files to Page Add files/images from a folder to a selected page. Page Active Languages Batcher Lets you enable or disable active status of multiple languages on multiple pages at once. Page Manipulator Uses an InputfieldSelector to query pages and then allows batch actions on the matched pages. Page Table To Repeater Matrix Fully converts an existing (and populated) PageTable field to either a Repeater or RepeaterMatrix field. Template Fields Batcher Lets you add or remove multiple fields from multiple templates at once. Template Roles Batcher Lets you add or remove access permissions, for multiple roles and multiple templates at once. User Roles Permissions Batcher Lets you add or remove permissions for multiple roles, or roles for multiple users at once. Creating a New Action If you create a new action that you think others would find useful, please add it to the actions subfolder of this module and submit a PR. If you think it is only useful for you, place it in /site/templates/AdminActions/ so that it doesn't get lost on module updates. A new action file can be as simple as this: <?php namespace ProcessWire; class UnpublishAboutPage extends ProcessAdminActions { protected function executeAction() { $p = $this->pages->get('/about/'); $p->addStatus(Page::statusUnpublished); $p->save(); return true; } } Each action: class must extend "ProcessAdminActions" and the filename must match the class name and end in ".action.php" like: UnpublishAboutPage.action.php the action method must be: executeAction() As you can see there are only a few lines needed to wrap the actual API call, so it's really worth the small extra effort to make an action. Obviously that example action is not very useful. Here is another more useful one that is included with the module. It includes $description, $notes, and $author variables which are used in the module table selector interface. It also makes use of the defineOptions() method which builds the input fields used to gather the required options before running the action. <?php namespace ProcessWire; class DeleteUnusedFields extends ProcessAdminActions { protected $description = 'Deletes fields that are not used by any templates.'; protected $notes = 'Shows a list of unused fields with checkboxes to select those to delete.'; protected $author = 'Adrian Jones'; protected $authorLinks = array( 'pwforum' => '985-adrian', 'pwdirectory' => 'adrian-jones', 'github' => 'adrianbj', ); protected function defineOptions() { $fieldOptions = array(); foreach($this->fields as $field) { if ($field->flags & Field::flagSystem || $field->flags & Field::flagPermanent) continue; if(count($field->getFieldgroups()) === 0) $fieldOptions[$field->id] = $field->label ? $field->label . ' (' . $field->name . ')' : $field->name; } return array( array( 'name' => 'fields', 'label' => 'Fields', 'description' => 'Select the fields you want to delete', 'notes' => 'Note that all fields listed are not used by any templates and should therefore be safe to delete', 'type' => 'checkboxes', 'options' => $fieldOptions, 'required' => true ) ); } protected function executeAction($options) { $count = 0; foreach($options['fields'] as $field) { $f = $this->fields->get($field); $this->fields->delete($f); $count++; } $this->successMessage = $count . ' field' . _n('', 's', $count) . ' ' . _n('was', 'were', $count) . ' successfully deleted'; return true; } } This defineOptions() method builds input fields that look like this: Finally we use $options array in the executeAction() method to get the values entered into those options fields to run the API script to remove the checked fields. There is one additional method that I didn't outline called: checkRequirements() - you can see it in action in the PageTableToRepeaterMatrix action. You can use this to prevent the action from running if certain requirements are not met. At the end of the executeAction() method you can populate $this->successMessage, or $this->failureMessage which will be returned after the action has finished. Populating options via URL parameters You can also populate the option parameters via URL parameters. You should split multiple values with a “|” character. You can either just pre-populate options: http://mysite.dev/processwire/setup/admin-actions/options?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add or you can execute immediately: http://mysite.dev/processwire/setup/admin-actions/execute?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add Note the “options” vs “execute” as the last path before the parameters. Automatic Backup / Restore Before any action is executed, a full database backup is automatically made. You have a few options to run a restore if needed: Follow the Restore link that is presented after an action completes Use the "Restore" submenu: Setup > Admin Actions > Restore Move the restoredb.php file from the /site/assets/cache/AdminActions/ folder to the root of your site and load in the browser Manually restore using the AdminActionsBackup.sql file in the /site/assets/cache/AdminActions/ folder I think all these features make it very easy to create custom admin data manipulation methods that can be shared with others and executed using a simple interface without needing to build a full Process Module custom interface from scratch. I also hope it will reduce the barriers for new ProcessWire users to create custom admin functionality. Please let me know what you think, especially if you have ideas for improving the interface, or the way actions are defined.3 points
-
Update: Jquery File Upload Version 0.0.3. Changelog Fixed an issue that caused duplicates in image gallery Some minor enhancements Glad to also announce that I've tested and can confirm that Jquery File Upload is compatible with ProcessWire 2.8.x and ProcessWire 3.x3 points
-
Yes it's possible with Field Dependencies. Set the visibility of the second field to yourDropdownFieldname=valueOfSecondSelect. The first field will take up the remaining space, if the second one is hidden. Edit: If your dropdown is a Page Field, the value should be the page ID of the selected item, not sure if it also works with the Select Options Field .. it should. If so, then it's the value you specified.3 points
-
Ok, this functionality is ready, although please test carefully at this stage. You can populate the option parameters via URL parameters. You should split multiple values with a "|" character. There are two options: 1) You can either just pre-populate the options values, but still showing the options page where you can make changes via the options form GUI: http://mysite.dev/processwire/setup/admin-actions/options?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add 2) or you can execute immediately with the passed options values: http://mysite.dev/processwire/setup/admin-actions/execute?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add Note the "options" vs "execute" as the last path segment before the parameters. Please try it out and let me know what you think. Do you think it might also be nice to have an option to redirect to another page after it has executed, rather than showing the results page? With your suggestion of linking from other places in the admin are you thinking about maybe an ajax call to an action, rather than loading the page? I haven't tested this yet, but it might be a nice option. I might even be able to return a JSON formatted response if called via ajax?3 points
-
New website for Fabrica Captial – Commercial Real Estate Investment http://fabrixcap.com/ (previously at http://www.fabricacapital.com/) Design by http://crookdesign.co.uk/2 points
-
Hi @mmc, welcome to the forums. It strikes me as unusual to use CKEditor in a contact form - I don't think I've ever seen a contact form that invites the visitor to submit their message using an RTE. A plain textarea is more typical. But anyway... For width you can set the inputfield columnWidth property: $field->columnWidth = 25; // sets width to 25% Or you can just set the width of the element that contains CKEditor in your CSS. For height, InputfieldCKEditor extends the InputfieldTextarea class so you can use the rows property: $field->rows = 3;2 points
-
Thanks for sharing! Some things overlap in weird ways, and some margins/paddings seem to be missing, probably because of these, I do not think I see what I should (/buy, /payments): GET http://www.spencersestateagents.co.uk/site/assets/aiom/js_5cf825d5af1afb7cc3d19fe864190e3e_dev.js?no-cache=1480610263 404 (Page Not Found) Failed to load resource: the server responded with a status of 404 (Page Not Found) 2js_5cf825d5af1afb7cc3d19fe864190e3e_dev.js Failed to load resource: the server responded with a status of 404 (Page Not Found) css_f27cbefaf407591de9d490a96da59494_dev.css Failed to load resource: the server responded with a status of 404 (Page Not Found)2 points
-
Processwire is more like David's car. They're both a nice piece of K.I.T.T ....2 points
-
Should not look dodgy, I just tested it with 3 columns as well. Works. Field widths are 33%, 34%, 33% to make 100%. Edit: Ah now I know what you mean, yeah ... well. Not out of the box, you might want to inject some custom JS to take care of that. Or you populate the second empty field on page save with a hook: // not tested, off the top of my head $pages->addHookAfter('save', null, function($event) { $page = $event->arguments(0); if (!$page->secondField) { $page->secondField = $page->firstField; $page->save("secondField"); } }); Don't know about the second thing.2 points
-
Well you should get to work on one then Send me a PR with a new action and I can work on the ajax response to suit your needs and we'll take it from there!2 points
-
If you want you can try my flexbox grid. It is configurable and based on Sass. Only issue (I guess) is that it hasn't been used by many users yet so you may find some bugs, I am using it on live websites with great results though. Note as well that you need at least IE10 for this grid. https://microcipcip.github.io/gridy/#!/ If you are using Sass with Ruby, it definitely is worth the hustle! Node Sass uses LibSass that is a C++ implementation of Sass, and it is extremely fast. Usually on big websites it doesn't take more than few milliseconds to compile. My workflow is Gulp + Sass + Autoprefixer, then I install thoughtbot Bourbon and Bitter plus a custom made mixin for the media queries2 points
-
UPDATED Thank you to everyone responded. I am closing this post since it's already been fulfilled. ======================================================================== Hi, We are Adnet Inc., a full service web development/hosting/maintenance company from Vancouver, BC. We're looking for contract front-end developer(s) to implement PW sites. PM me to discuss. Cheers, Rudy Affandi rudy@adnetinc.com2 points
-
In memory search is only possible if the to be searched element is already retrieved, which means only if you call find on a PageArray. You're calling find on a Page object, which is just syntax sugar for $pages->find("parent=$booking, …") . I'd suggest you using https://blackfire.io/ for profiling. It's the best tool to look into the system I've ever used. With few parts of ProcessWire being called all over the place it requires a bit searching to find the exact part of code you actually can improve on, but it's worth for not needing to guess. To improve on plain query count (not necessarily speed) you go this way: $bookings = $pages->get('/bookings/')->find('room=roomOne'); // 2 queries foreach($bookings as $booking) $roomData = $booking->find('date=' . $today); // n queries // Improved $bookings = $pages->find('parent=/bookings/, room=roomOne'); // 1 query $roomsData = $pages->find("parent=$bookings, date=$today"); // 1 query foreach($bookings as $booking) $roomData = $roomsData->find("parent=$booking"); Edit: Just to add this here. Doing database queries in foreach loops is almost always to be avoided.2 points
-
Database. If it was an in-memory query, the first find() operation would need to return every single child page along with the pages actually matching the query. I don't know anything about your structure, but it appears that you have "room pages" below /bookings/ and each room page has a variable number of booking pages as it's direct children, right? In the first query, if you're only interested in the direct children of /bookings/, you should use children() instead of find(). You should get a notable speed bump from this alone. Additionally: while this is probably not production code, please note that with every find() operation that has the potential to match a large number of results you should use limit, or otherwise you'll risk running into both performance and memory issues at some point.2 points
-
Dynamic Selects Released 27 July 2016 Dynamic Selects is a commercial module that enables the creation of dynamically related/dependent ajax-driven chained dropdown lists (aka cascading selects) for display and storage of multiple types of data. The module can be used both in the front- (display only) and backend (display and storage of data). Setting up Dynamic Selects is very easy. With minimal effort, site developers can set up simple or complex chained selects. By making a selection in a trigger dropdown, via ajax, values are fetched and dynamically populate options in the dependent select. In turn, making a selection in the now populated select triggers the same action further down in a dependent select. The module only uses/stores ID references to selected options in the selects meaning the most current/up-to-date data will always be displayed in the selects. Currently only ProcessWire managed data are supported. If there is enough demand, we may incorporate external data sources (typically JSON). The module consists of 4 modules ProcessDynamicSelects MarkupDynamicSelects FieldtypeDynamicSelects InputfieldDynamicSelects Video Demo: https://youtu.be/wkhx8xQ5ue4 Documentation: http://dynamicselects.kongondo.com/ Shop: https://processwireshop.pw/plugins/dynamic-selects/ Requires: ProcessWire 2.5 or newer and jQuery if using the frontend module (MarkupDynamicSelects) Features Easily create powerful ajax-driven cascading/chained selects/dropdowns Unlimited number of select dropdowns per field Data-mapping made easy thanks to multiple possible combinations of data relationships, triggers and sources Mutlipe data relationships to chose from ID-based data referencing ensures your data values always stay fresh Remote and local caching to speed up data access and reduce ajax-requests to server User-friendly, intuitive and easy to set up IMPORTANT Before using this module in the frontend, you will need to thoroughly read the security section in the documentation.1 point
-
MarkupCache is a simple module that enables you to cache any individual parts in a template. I'm working on a site now that has 500+ cities in a select pulldown generated from ProcessWire pages. Loading 500+ pages and creating the select options on every pageview isn't terribly efficient, but I didn't want to cache the whole template because it needed to support dynamic parameters in the URL. The solution was to cache just the code that generated the select options. Here's an example: $cache = $modules->get("MarkupCache"); if(!$data = $cache->get("something")) { // ... generate your markup in $data ... $cache->save($data); } echo $data; I left the markup generation code (the part that gets cached) out of the example above to keep it simple. Below is the same example as above, but filled out with code that finds the pages and generates the markup (the part that gets cached): $cache = $modules->get("MarkupCache"); if(!$data = $cache->get("city_options")) { foreach($pages->find("template=city, sort=name") as $city) { $data .= "<option value='{$city->id}'>{$city->title}</option>"; } $cache->save($data); } echo $data; That was an example of a place where this module might be useful, but of course this module can used to cache any snippets of code. By default, it caches the markup for an hour. If you wanted to cache it for a longer or shorter amount of time, you would just specify the number of seconds as a second parameter in the get() call. For example, this would keep a 60-second cache of the data: $cache->get("city_options", 60) I hope to have it posted to GitHub soon and it will be included in the ProcessWire distribution. If anyone wants it now, just let me know and I'll post it here or email it to you.1 point
-
1 point
-
Not sure that you need to do the first pipe replace - you could just explode on commas and then trim(). You'll add the pipe when you implode. Also, passing by reference in a foreach can catch you out so perhaps better to avoid it. // Explode search input into array $search = explode(",", $input->get->search); // Sanitize each value foreach($search as $key => $value) { $search[$key] = $sanitizer->selectorValue(trim($value)); } But otherwise it looks fine to me; that's what I would do.1 point
-
Sorry about that, I was just doing some urgent updates after posting. Should be all good now thanks for pointing it out.1 point
-
hey @DedMoroz, That was a long time ago and I'm not quite sure I remember the details but let me try. Where have you placed your Hybridauth folder? If you put Hybridauth in the site/ directory, it will use the default PHP session.save_path. Your template in Processwire uses pw's session path (assets/sessions). You need to ensure that both the session paths are same for it to work. You can do this by commenting the following line in index.php //if(ini_get('session.save_handler') == 'files') ini_set("session.save_path", rtrim($config->paths->sessions, '/')); This will make pw's session.save_path as the default PHP session.save_path. Now session variables can easily be passes between PW and Hybridauth templates.1 point
-
Are you sure it's the db and not any of your php files or incorrect html encoding?1 point
-
Ah I see Will look into these options ^^ Thanks a lot for the help!1 point
-
1 point
-
1 point
-
Thanks, it's a great step forward A JSON return would be great - I think a use case could be established first to see how this could work.1 point
-
Currently it's not possible. I could redesign the image sets like this: { "featured": [ [435,210], 2, 4 ], "hero": [ "720w 990w 1220w" => [ [720,320], 2, 3 ] ] } It's getting a bit complicated but if I'll have some time I could create an UI for this so it will be easier to set.1 point
-
Hi @heldercervantes. It looks very similar to my issue, checkout this topic1 point
-
Announcing that I've tested and can confirm that RuntimeMarkup is compatible with ProcessWire 2.8.x and ProcessWire 3.x1 point
-
Hello @heldercervantes, inside includes the following string translation should work: $this->_('Follow us'); Regards, Andreas1 point
-
Scratch that idea. I added a 2nd field for body images with unlimited uploads. Then when inserting via RTE the images just insert to this 2nd field. Seems more intuitive to me. I don't really need to select from other pages when I think about it. Admin for a basic page looks like: Title Main image Summary (RTE limited formatting options) Additional images (for body content) Body content (RTE full formatting options) Works great, another +1 for processwire in my book.1 point
-
@kongondo, at the end of the select chain one might want to select multiple things, like on regular page selects. For example a list of employees: Company > Location > Department > Jane Doe, John Doe and Max Mustermann1 point
-
@FrancisChung good question. Any business logic should be separated from the view layer. A template is a view, code there should not be complex. Loops, perhaps some string concatenations, value calls, nothing more. You want a template designer not to fiddle with your code and perhaps even break something. Even if you are the template designer. For complex logic use Modules, Template Data Providers or something like the Controller/View separation used in Template Engine Factory I understand that this is perhaps not the ProcessWire way, right out of the box, or at least not something that is advocated too much, but I think it's because ProcessWire does not dictate how you use it. MVC ... or just VC in this case is just one way to do it. For simple sites perhaps overkill but if your code grows more complex, the VC concept makes the project more sustainable and it's a well established concept.1 point
-
Ok, the optional author links are now available. These are the current options: protected $authorLinks = array( 'pwforum' => '985-adrian', 'pwdirectory' => 'adrian-jones', 'github' => 'adrianbj', );1 point
-
Let me think about this a little more - even in a dev environment restoring to a really old backup could be disastrous if you're still developing the site. I guess that's the responsibility of the dev to be smart about things though. I like it - I think giving authors proper credit will hopefully promote more contributions. I have gone with PW developer directory link, PW forum profile, and also Github account, with linked icons. I could maybe provide the option for the author to fully customize their links, but don't want things getting too ugly. Any thoughts?1 point
-
@adrian How about adding: protected $authorForumsProfile = '985-adrian'; so that one can more easily identify the author? Should be used as trailing part of the href attribute, of course1 point
-
Underscores in host names are invalid according to RFC1132, which allows only letters, digits and hyphens. They are only allowed in DNS names for resource records. So PW is operating in undefined territory.1 point
-
Let's inform them Jokes aside, the db backup module is supported by Ryan, so it should be safe to rely on it. Sensible use cases would dictate to try things out in a development environment not on a live site, so I would not worry too much about this.1 point
-
Just to add to your testing, I can confirm that I have been using this awesome module with 3.x for probably 6 months now without any problems!1 point
-
Announcing that I've tested and can confirm that ImageMarker is compatible with ProcessWire 2.8.x and ProcessWire 3.x1 point
-
Just announcing that I've tested and can confirm that Matrix is compatible with ProcessWire 2.8.x and ProcessWire 3.x1 point
-
Are you running PW 3? In that case, make sure you use the FieldtypePDF module downloaded from the devns branch at github, not the one in the modules repo.1 point
-
As you've already found nico's textformatter you could also use a:not(.external) to get all internal links.1 point
-
First things first: what do you need this for? If it's a style-related thing use attribute selectors instead. Basically the same thing goes for JavaScript stuff. If you really need a server-side solution to this, the polite thing to do would be giving it a try yourself before asking someone to do it for you. That being said, what you are asking for would mean a) checking that the link isn't relative (href="/foo/" or href="index.html") and b) checking that it doesn't point to your own site (href="your-own-site...) It's really not a very difficult thing to do if you put your mind to it, so why don't you give it a try and if you run into any issues ask help with those?1 point
-
1 point
-
Hi iNoize, Checkout this example used by Ryan to view tags in his blog profile: <?php /** * Generate a list of tags A-Z * * Used by the /site/templats/tags.php template file. * * VARIABLES: * ========== * $tags PageArray of tags * * Each of the tags has a numPosts property containing the number of posts used by the tag. * */ $lastLetter = ''; $out = ''; $letters = array(); foreach($tags as $tag) { $letter = strtoupper(substr($tag->title, 0, 1)); if($letter != $lastLetter) { if($lastLetter) $out .= "</ul>"; $out .= "<h3 id='letter_$letter'>$letter</h3>"; $out .= "<ul class='tags posts-group'>"; $letters[] = $letter; } $lastLetter = $letter; $numPosts = sprintf(_n('%d post', '%d posts', $tag->numPosts), $tag->numPosts); $out .= "<li><a href='{$tag->url}'>{$tag->title}</a> <span class='num-posts'>$numPosts</span></li>"; } $out .= "</ul>"; echo "<p class='jumplinks'>"; foreach($letters as $letter) { echo "<a href='./#letter_$letter'>$letter</a> "; } echo "</p>"; echo $out;1 point
-
Sounds good. I already need to be working on this for a few personal projects I want to implement. I'll look at your source more closely and see if I can make similar design decisions to streamline payments workflow on PW. Cheers!1 point