Leaderboard
Popular Content
Showing content with the highest reputation on 12/18/2014 in all areas
-
FieldtypeMatrix and InputfieldMatrix Modules Directory: http://modules.processwire.com/modules/fieldtype-matrix/ GitHub: https://github.com/kongondo/FieldtypeMatrix The module Matrix enables you to save data from a 2D-Matrix table. The rows and columns of the matrix table are made up of pages retrieved via a ProcessWire selector or via a page field selection of parent pages. The matrix values are made up of the data input in the matrix cells, i.e. the 'intersection of rows and columns'. Example Usage You have Products whose prices vary depending on colour, size, material, etc. Using the Fieldtype, you can create a table with rows made up of colours and columns made up of sizes the combination of each making up their respective values (in this case price). So rather than creating multiple text fields to do the following: Colour Size Price Red Small £10 Red Medium £20 Red Large £30 Red X-large £35 Green Small £9 Green Medium £15 Etc... You can instead have the following in one field: Small Medium Large X-Large Red £10 £20 £30 £35 Green £9 £15 Blue Etc... Yellow Purple If you set a selector in the Field's settings, to retrieve pages to build your matrix's rows and columns, it follows that all pages using the template the Fieldtype is attached to will have identical rows and columns. In some cases, this could be the intention. For instance, you might have 'Car' pages, e.g. Audi, Volvo, Ford, Citroen, Mazda, BWM, etc., each of which uses a 'Cars' template that has a single FiedltypeMatrix called 'car_attributes'. If you set a selector to build the Fieldtype's rows and columns, your users can easily compare the cars based on a combination of different values. The following matrix table best illustrates this: Type Engine Size Fuel Efficiency Carbon Emissions Warranty Road Tax Price 1994 Audi brand 1 values, etc. 2000 Audi brand 2 2006 Audi brand 3 2012 Audi brand 4 Each of your car pages would have similar matrices. This allows you to make easy but powerful queries. Such a setup allows you to compare within and across car brands. Say you wanted to find out which car(s) offered the best value for money given certain parameters such as warranty, emissions etc. You can easily make such comparisons (see code below). You can also compare within one car type, e.g. which brand of BMWs does best in what area...The possibilities are endless. In the database, Rows and column pages data are stored as their respective page->id. Matrix-values store any data (varchar(255)). If instead you wanted a template's pages to each have a matrix built of different rows and columns, you would have to name a Multiple Page Field (attached to the same template as the as your matrix field) in the matrix field's settings. When editing those pages, your matrix table's rows and columns will be built using the published children pages of the 2 pages you select in the Multiple page field.. The module allows the creation of matrix tables of any sizes (rows x columns). The rows and columns dynamically grow/shrink depending on the addition of row/column pages that match what you set in the matrix field's settings (see its 'Details Tab'). Please note that, if such pages are deleted/trashed/hidden/unpublished, their data (and presence) in the matrix are also deleted. Entering values in the matrix You have three choices: Manually entry Uploading a comma delimited (CSV) file. This can be delimited by other characters (tab, pipe, etc); not just commas Copy-pasting CSV values. (Tip: you can copy paste directly from an Excel spreadsheet. Such values will be 'tab-delimited'). In addition, if your server supports it, in the field's settings, you can enable the use of MySQL's fast LOAD DATA INFILE to read and save your submitted CSV values. Note that for large tables, you may have to increase your PHP's max_input_vars from the default 1000 otherwise PHP will timeout/return an error and your values will not be saved. I have successfully tested the module with up to ~3000+ values (10x350 table), the Fieldtype is not really optimised (nor was it intended) to handle mega large matrix tables. For such, you might want to consider other strategies. Install Install as any other module. API + Output A typical output case for this module would work like this: The matrix's rows, columns and values are subfields of your matrix's field. So, if you created a field called 'products' of the type FieldtypeMatrix, you can access as: product.row, product.column and product.value respectively foreach($page->matrix as $m) { echo " <p> Colour: $m->row<br /> Size: $m->column<br /> Price: $m->value </p> "; } Of if you want to output a matrix table in the frontend: //create array to build matrix $products = array(); foreach($page->matrix as $m) $products[$m->row][$m->column] = $m->value; $tbody ='';//matrix rows $thcols = '';//matrix table column headers $i = 0;//set counter not to output extraneous column label headers $c = true;//set odd/even rows class foreach ($products as $row => $cols) { //matrix table row headers (first column) $rowHeader = $pages->get($row)->title; $tbody .= "<tr" . (($c = !$c) ? " class='even' " : '') . "><td class='MatrixRowHeader'>" . $rowHeader . "</td>"; $count = count($cols);//help to stop output of extra/duplicate column headers foreach ($cols as $col => $value) { //matrix table column headers $columnHeader = $pages->get($col)->title; //avoid outputting extra duplicate columns if ($i < $count) $thcols .= "<th class='MatrixColumnHeader'>" . $columnHeader . "</th>"; //output matrix values $currency = $value > 0 ? '£' : ''; $tbody .= "<td>" . $currency . $value . "</td>"; $i++; } $tbody .= "</tr>"; } //final matrix table for output $tableOut = "<table class='Matrix'> <thead> <tr class=''> <th></th> $thcols </tr> </thead> <tbody> $tbody </tbody> </table>"; echo $tableOut; The module provides a default rendering capability as well, so that you can also do this (below) and get a similar result as the first example above (without the captions). echo $page->matrix; Or this foreach($page->matrix as $m) { echo $m; } Finding matrix items The fieldtype includes indexed row, column and value fields. This enables you to find matrix items by either row types (e.g. colours) or columns (e.g. sizes) or their values (e.g. price) or a combination of some/all of these. For instance: //find all pages that have a matrix value of less than 1000 $results = $pages->find("products.value<1000"); //find some results in the matrix (called products) of this page $results = $page->products->find("column=$country, value=Singapore");//or $page->products->find("column=$age, value>=25"); //$country and $age would be IDs of two of your column pages Other more complex queries are possible, e.g. find all products that are either red or purple in colour, come in x-large size and are priced less than $50. Credits @Ryan on whose Fieldtype/InptufieldEvents this is largely based @charger and @sakkoulas for their matrix ideas Screens Field Details Tab Inputfield Larger matrix table Example output16 points
-
I did my first fork and pull request with git - which turned out to be far less mysterious than anticipated - and Ryan already accepted my fix. Thanks!5 points
-
Here's my first serious attempt at a PW module. I have the need that pages shouldn't be "published" in all languages at once, so I've put together a PageLangPublish module. It adds both buttons for publishing/unpublishing of each language to the page tree and status icons (from image fields added to each page in admin/languages) next to the page title in the tree. You can find the module at github under https://github.com/BitPoet/PageLangPublish I've probably done a lot of things quite awkwardly (even incorrectly) there, so I'd be grateful for any pointers and ideas. The module also adds a hookable isLanguageViewable method to the Page class. Usage example: $topnav = array(); foreach($homepage->children as $item) { if( $item->isLanguageViewable($user->language) ) { $topnav[] = "<a class='topnav' href='{$item->url}'>{$item->title}</a>"; } } echo implode(" | ", $topnav); Here's a screenshot:4 points
-
i've had too much wordpress in the last 6 months. 130 hours building an ecommerce site using woocommerce; now 10 hrs restoring a hacked site for a friend who didn't backup. My message to anyone reading this who might try and Wordpress: Don't Do It!4 points
-
This module is improved and extended successor to Version Control For Text Fields. It handles everything it's predecessor did -- providing basic version control features for page content -- and quite a bit more. Download or clone from GitHub: https://github.com/teppokoivula/VersionControl. This module requires ProcessWire 2.4.1 or later, mostly because of the file features, which require certain Pagefile and Pageimage methods to be hookable. There's no sensible way around this limitation; for those stuck with < 2.4.1, Version Control For Text Fields will remain a viable option. What does it do? While editing pages, fields with old revisions available show up with a new icon in their header bars. By hovering that icon you get a list of available revisions and by clicking any one of those the value of that particular field is reverted to that revision. No changes are made to page until you choose a revision and save the page, which means that you can keep switching between revisions to get an idea what's really changed without inadvertently causing any content to change. The module also adds a History tab to page edit. This tab opens a view to the history of current page in the form of "revisions" -- each of which is a group of changes to page fields processed during one page save (similar to revisions in various source control applications). There are three actions you can perform on these revisions: adding comments, live previewing what the page might've looked in that revision and restoring the page to specific revision. One specific feature that has been a big thing for me personally is support for file (and image) fields, as the original version control module felt rather incomplete without it. I'm hoping to take this a lot further performance, stability and feature wise, but as it stands right now, it's already included here and should be fully functional. Watch the video preview here I prepared a little screencast outlining most of this: http://youtu.be/AkEt3W7meic. Considering that it was my first screencast ever, I'd like to think that it wasn't that bad.. but I might give it another shot at some point, this time planning a bit before hitting "record" Upgrading from Version Control For Text Fields For those already using Version Control For Text Fields, I've added something extra. If you upgrade that module to it's latest version, you should see a new checkbox in it's settings screen saying "Don't drop tables during uninstall". If you check this, uninstall the module and then remove it's files (this is required in order to install Version Control), your old data should be automagically imported to Version Control. Import has only been tested with limited amounts of demo data. Proper tests are yet to come, so please be careful with this feature! Update, 21.6.2015: as of today, this module is no longer in beta. While all the regular warnings still apply (making changes, including installing any new modules, on a production site should always be considered risky) Version Control has gone through pretty extensive testing, and should be as stable as any other module out there.3 points
-
What PW version? That's why I'm not using clone tool. But see others using it all the time. This bug is not something you'll recognize unless you use has_parent, and I think there's lots of PW sites where this happens and nobody recognized it yet. It's that the parents table is broken for those. It's annoying cause once you stumble over it you have no idea whats happening, or you don't even will ever notice that some pages may not get returned.3 points
-
My function is totally useless. This is the decision I was looking for. Have not done my homework. I never found $page->find() - probably confused it with $pages->find() every time visiting the cheatsheet. I think has_parent selector, which I was deliberately looking for so many times with no success, can also do the job. I need stronger glasses.3 points
-
If I understand correctly, this could be done easily with a page field added to the user template. To access the user template, go to the templates page and click Filter > Show System Templates. The Page field (probably ASM Select) that you add would be linked to all the film pages. So you'd just select the films they are allowed to view. Then in your template files you can check whether the user has the film selected before showing it in the list of films for them to watch. Let me know if anything there doesn't make sense. EDIT: Of course it could also be done from the other direction. The template for the films could have a page field that contains a list of all the users and you could choose which users can view the film. You might want to consider PageAutocomplete as the Inputfield type if you end up with a lot of films / users.3 points
-
I love the Telecrapper. Some guy hooked his landline up to a computer which could recognise incoming cold calls by their number. His computer would then kick in with a series of random conversations he'd pre-recorded. Here's a recording http://www.ebaumsworld.com/flash/play/464574/ Here's the guys homepage http://myplace.frontier.com/~pumamanor/ At the end of that page theres a few great audio files although the sound quality isn't great.3 points
-
Sitting here listening to the many scam phone calls my mother receives on her landline (and probably would on her mobile if she used it), I would love to have a little jokey functionality that simply did the following. On receipt of scam insurance, ppi, car accident, lottery or computer security call, she would simply press a button: SFX: Blaze of deafening siren down phone line (must make their ears bleed) SFX: (Under v/o) Dialling number bleeps (siren fades to background) Female VO (Authoritative): Your call has caused a security alert. Your number and location are being traced and security authorities have been notified. Please cease and desist, stay seated and place your hands on your head. Your company will now be subject to an official investigation. It is vital that you remain exactly where you are. Failure to do so will be seen as non-cooperation and will be subject to criminal proceedings. This message is an automated advisory. SFX: Bleeping and Siren stops abruptly. VO: Trace completed. Please wait for your local security forces. END Okay, so it is as fake as they are and they probably will only hear a few words of it before they hang up, but I would feel loads better having triggered it! PS: When I receive these calls, I now make it a policy not to hang up immediately as the gov suggest, but to get angry and foul mouthed and make their day as miserable as possible. If everytime they made a call they got an earful of very personal abuse, I am sure they would start looking for alternative careers after a while.... PPS: Multi language versions would also be cute .... PPPS: since so many of these calls originate from Indian call centres and English is the Lingua Franca of Calcutta, Mumbai and so on, do English speaking countries suffer from more of these than, say, German or French countries?2 points
-
@ Ivan Thats not true. Now you cannot use any field of the parent page to generate the name. Only the generation from date function is possible now. Try it out! But with my solution you could use all the parent page fields + date + some string in the order you want it. This is obviously more + inclusion what we have. About title: Now you get, whatever you defined in the setting the title 'untitled' or a title generated from date which you maybe want to overwrite anyway! No other possibilities until now! Maybe I understoud you completely wrong, or you my solution. Have a look in github.2 points
-
You have moved those pages around from amother parent? Move those out of the parent and then back in. Works?2 points
-
Yeah, we have the same thing in Canada, but it doesn't do S*&t!!! I almost think some companies are using it as a free call database to work with2 points
-
Joomla just recently changed their release strategy. I never heard we at PW have one )) I think we're mature enough to think about it. It seems a little strange to just freeze a version not providing any bug fixes in stable branch. Of course, it is strange only if you don't know how many people named Ryan from Atlanta are working on it . Anyway, clear release strategy is a must have to grow and to possibly involve more people in the development/bug fixing. Not sure what comes first though: strategy or more people .2 points
-
@sakkoulas, Posted this on Github and started the new module's topic here: https://processwire.com/talk/topic/8581-module-matrix-fieldtype-inputfield/ Thanks for testing! Also see subsequent post there about some thoughts I am having, thanks.2 points
-
True enough, Teppo - but like anything automated, it is a good way of starting the analysis. So you have 50 submitted modules to check, start by something automated and those that fail go straight in the bin. Those that pass, then go onto further scrutiny. It all fails when automated systems are the LAST stop rather than the first2 points
-
I guess this counts as "on the web": http://www.phparch.com/magazine/2014-2/december/.2 points
-
@apeisa: definitely. I've been test-driving a few locally-hosted solutions, with mixed results (some were "kind of useful", but none really convinced me). Sensio Insight seems interesting alternative, though so far it seems to think that my code is safe, which is a huge red flag to me .. oh, and for the record: programmatic vulnerability scanning is helpful, but I'm always a bit worried that people could trust it too much. There are too many logical issues for it to be "perfect", and thus it might give some users false feeling of safety.2 points
-
This is the key point here: API. It improves the security a lot compared to having to rely on plain SQL, which is always more or less prone to human error, leading to injection vulnerabilities, etc. Another thing is that most modules seem to avoid potentially harmful methods like exec, shell_exec, passthru, etc. Not sure if that's really anything specific to ProcessWire, though Anyway, one can still easily write a ProcessWire module that trusts user input too much, or trusts input from wrong users, or simply displays too much to unauthorised users. This is why some sort of security audit process would be most welcome, though perhaps as an addition, not something that automatically applies to every module submitted to the modules directory.2 points
-
The thing with Processwire, for the security conscious, is that you can create a huge variety of sites and address many different types of content WITHOUT touching any plugins other than what comes from Ryan's safe hands. You can add all the seo stuff you would ever need, add connections to social websites with links and opengraph or whatever, add caching and so on, without ever having to move outside the box - you just stick them in your template files and feed them from a field somewhere. And if you want singing and dancing with JQuery plugins, again, you just use them raw - you don't have to set up new database connections or anything else clever to make them Pw compliant - you only use the trusted API and keep the two well and truly apart. With WP, on the other hand, if you want anything more than the simplest of blogs, you are already on a plugin-fest from hell before you ever get going. Noting all that, I think it is VITAL that this principle is sustained with processwire with the vast majority of modules being about admin functionality (and vetted first as much as possible) and front end functionality left to the site development where the developers can make reasoned choices. If you want a completely plug-n-play CMS, unfortunately that will ALWAYS come with plug-n-play security issues ....2 points
-
1) There are no plans to drop support for it, if that's what you're asking -- so yes, it can be considered a longterm solution. On the other hand, you might consider that with ProcessWire you don't really have to upgrade your site every time a new release comes out, so in that sense it wouldn't even matter that much if specific core feature was, at some future point, superseded by something different. ProcessWire isn't like some other systems, where just about every upgrade is essentially a security fix -- so far there have been no vulnerabilities in the core code, and we intend to keep things like that. There's also one potential gotcha here: what you're describing above kind of sounds like you'd benefit more from the Multisite module instead of the core multisite support. With core multisite support all your sites share common core code, but have their own templates, site-specific modules and databases. Essentially they're separate sites with some shared codebase. That's important when/if you, for an example, need to re-use data from one site to another. With Multisite module there's one base site, and all other sites live in the same page tree but can be accessed with their own domains. By default they share same templates, modules, etc. in addition to the core code, and can also use content from each other (or the base site) easily. Note: multisite module sharing same templates doesn't mean that you can't customise templates per site. The workflow is just a bit different. It's also important to consider when it comes to managing said sites. Multisite module makes it easy to manage all sites from one place (i.e. the "subsites" are just branches in the main sites page tree), while with the core multisite support they're separate sites, with their own user accounts, admin views, etc. If your sites are going to be managed by different people anyway, this probably isn't much of a benefit, so it does really depend on your use case 2) If you're referring to the commercial modules mentioned above, that depends on how you use them in your setup, and there might be some limitations. You might want to check this out first by contacting the module author (Ryan) directly. I'm not entirely certain on the details at the moment, and wouldn't want to spread any misinformation here 3) Yes and no -- not exactly identical, but we've built a few multisite setups. The biggest issue has usually been the management part, i.e. how it should be handled in the first place, what happens when later on the client decides that each site does indeed require specific permissions, etc. Most of that is now much easier than it was just a few years ago. Permission management, for an example; modules like UserGroups and Dynamic Roles have made a huge impact in this area. Hope this helps a bit!2 points
-
This module adds CSV import and export functionality to Profields Table fields on both the admin and front-end. http://modules.processwire.com/modules/table-csv-import-export/ https://github.com/adrianbj/TableCsvImportExport Access to the admin import/export for non-superusers is controlled by two automatically created permissions: table-csv-import and table-csv-export Another permission (table-csv-import-overwrite) allows you to control access to the overwrite option when importing. The overwrite option is also controlled at the field level. Go to the table field's Input tab and check the new "Allow overwrite option" if you want this enabled at all for the specific field. Please consider limiting import overwrite option to trusted roles as you could do a lot of damage very quickly with the overwrite option Front-end export of a table field to CSV can be achieved with the exportCsv() method: // export as CSV if csv_export=1 is in url if($input->get->csv_export==1){ $modules->get('ProcessTableCsvExport'); // load module // delimiter, enclosure, file extension, multiple fields separator, names in first row $page->fields->tablefield->exportCsv('tab', '"', 'tsv', '|', true); } // display content of template with link to same page with appended csv_export=1 else{ include("./head.inc"); echo $page->tablefield->render(); //render table - not necessary for export - just displaying the table echo "<a href='./?csv_export=1'>Export Table as CSV</a>"; //link to initiate export include("./foot.inc"); } Front-end import can be achieved with the importCsv() method: $modules->get('TableCsvImportExport'); // load module // data, delimiter, enclosure, convert decimals, ignore first row, multiple fields separator, append or overwrite $page->fields->tablefield->importCsv($csvData, ';', '"', true, false, '|', 'append'); Please let me know if you have any problems, or suggestions for improvements. Enjoy!1 point
-
As described in this post (https://processwire.com/talk/topic/8551-custom-urls-for-pages/?p=82742) the option 'Name Format Children' under the tab 'Family' in template settings doesn't work properly and also not as expected. I had a look inside the code and made some changes which are working properly, which offers much more options, more consistency and less code too. The result is the following. You have 3 Options for generating name and title, which could be combined in endless variations. Name is always derived from title, same like creating pages manually. type date: if function detects # character anywhere in the string, conversion will be: deletion of # and string will be used as format parameter for PHP date() function type field: if string is a fieldname of the parent page the value of this field will be used type string: if string doesn't fit to the 2 preceeding it will be taken as it is All parts (separated by comma) will be composed in the order of setting. You can use unlimited numbers of parts I made a pull request on github: https://github.com/ryancramerdesign/ProcessWire/pull/831 Example screenshots Setting ... will result in1 point
-
Hello there, ProcessWire has been the perfect CMS for me so far but I always missed the Laravel way of doing things when working with PW. Therefore I've built a package that will integrate Laravel into ProcessWire. It's already working out really well and I can imagine a lot of stuff to come in future. Anyways I'm hoping for some peoples support / pull requests / ideas / opinions ... Here's the link: https://github.com/hettiger/larawire Enjoy!1 point
-
In this tutorial we make a simple function that becomes part of every PageArray. Once hooked to the PageArray class, you can call this function from anything returned from $pages->find(), $page->children(), or your own page references like $page->categories from the blog profile, etc. It essentially becomes a new function available to you from any PageArray anywhere in your site. First, lets look at what convenience the hook function adds and how we might use it. We'll call the hook function "renderLinks", but you could of course call it whatever you wanted. We call that renderLinks() function from any PageArray, and it returns a string representing that PageArray as a list of links. By default, this renderLinks() functions separates each page with a comma, and outputs the page's title as the anchor text. We can change that to be anything by specifying arguments to the call. The first argument is the delimiter, which defaults to a comma ", " if not specified. The second argument is the name of the field to output, which defaults to "title" if not specified. Next are 3 examples of how this renderLinks hook function could be used. Usage Examples: Example 1: render a comma-separated list of links: echo $pages->find("parent=/")->renderLinks(); Output: <a href='/about/'>About Us</a>, <a href='/contact/'>Contact Us</a>, <a href='/site-map/'>Site Map</a> Example 2: render a <ul> of $categories links: <ul> <li> <?php echo $page->categories->renderLinks('</li><li>', 'title'); ?> </li> </ul> Output: <ul> <li><a href='/categories/category1/'>Category 1</a></li> <li><a href='/categories/category2/'>Category 2</a></li> <li><a href='/categories/category3/'>Category 3</a></li> </ul> Example 3: render a breadcrumb trail: <p class='breadcrumbs'> <?= $page->parents->renderLinks(' / ') ?> </p> Output: <p class='breadcrumbs'> <a href='/parent1/'>Parent 1</a> / <a href='/parent1/parent2/'>Parent 2</a> / <a href='/parent1/parent2/parent3/'>Parent 3</a> </p> Those examples above show some of the potential of how you might use such a function. Next is the hook function itself. In order to be available to all templates in your site, it needs to be defined somewhere consistent that is always loaded... Where to put the hook function: If using the basic profile (that comes with ProcessWire) you could put the hook function at the top of your /site/templates/head.inc file. If using the Foundation or Skyscrapers profile, you could put the hook function in your /site/templates/_init.php file. This is the method that I use. If using something else, you could create a /site/templates/_init.php file with your hook function(s) in it, and then edit your /site/config.php to point to it with the $config->prependTemplateFile = '_init.php'; so that it is automatically loaded on every request. Note that the name "_init.php" is not required, you can name it whatever you want. You could put it in an autoload module... but that might be overkill here. The actual hook function: wire()->addHook("PageArray::renderLinks", function(HookEvent $event) { // first argument is the delimiter - what separates each link (default=comma) $delimiter = $event->arguments(0); if(empty($delimiter)) $delimiter = ", "; // second argument is the property to render from each $page (default=title) $property = $event->arguments(1); if(empty($property)) $property = "title"; // $out contains the output this function returns $out = ''; // loop through each item in the PageArray and render the links foreach($event->object as $page) { $value = $page->get($property); if(!strlen($value)) continue; // skip empty values if(strlen($out)) $out .= $delimiter; if($page->viewable()) { // if page is viewable, make it a link $out .= "<a href='$page->url'>$value</a>"; } else { // if page is not viewable, just display the value $out .= $value; } } // populate the return value $event->return = $out; }); If using PHP before 5.3, or using an older version of ProcessWire, you'll need to change the first line to this (below). This syntax also works with newer versions as well, but it's not as pretty as the new syntax. wire()->addHook("PageArray::renderLinks", null, 'hookRenderLinks'); function hookRenderLinks(HookEvent $event) {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
-
1 point
-
Or, going completely overboard using recursion, only loading pages to the requested depth: function getAncestors($pg, $level) { $retPages = (new PageArray())->add($pg); if( $level > 0 ) { foreach( $pg->children As $child ) $retPages->add(getAncestors($child, $level - 1)); } return $retPages; }1 point
-
Wow, that worked. What causes this? Is there any way to prevent it / workaround?1 point
-
Great stuff!! Thanks a lot! I did some testing, and everything seems to work. I have one feature that I'm missing. I'm aware this is not the core idea of this module, but I wanted to mention it anyway. Ok, so here it is: If I have a selector for columns/rows that goes like parent=1283|1284, it works as expected by listing the children of both parents. The output could be like this: S M L Cotton Nylon However, it would be cool to have an option (checkbox) that creates all possible combinations of the selected children, like this: S Cotton M Cotton L Cotton S Nylon M Nylon L Nylon In my case, I need this because I have multiple currencies for the rows. As mentioned, I don't know if this too much out of scope and maybe needs an additional module.1 point
-
We have the same in the UK - but it is impossible to insist that companies outside the UK take any notice. We made a mistake in telecoms many, many years ago by making numbers public by default; printed in a directory back then. Companies now believe they have an automatic right to your contact information unless you say otherwise. To me, that is fundamentally wrong. If a salesperson wants to sell to me, I expect them to go to the trouble of coming to my door so I can scare the bejeebers out of them!1 point
-
@Ivan Yes, the title is generated and the name too, as a derivation from the title. (have a look at the system notice on top of the screenshot) Derivation works completely in the same way, if you add a page manually and type in the page title. I think thats what most user would expect. You have read the post, where I described, how it is working actually (link in the first post of this topic). This way seems to be unlogical to me.1 point
-
Thanks Adrian, i'll give them a look now and get back to you. Thanks1 point
-
I haven't read through your code yet, but have you seen this module: http://modules.processwire.com/modules/inline-editor/ It is listed as proof of concept, but it might work for you, or help you solve the problems with your code. There is of course also Fredi: http://modules.processwire.com/modules/fredi/ and AdminBar: http://modules.processwire.com/modules/admin-bar/ - even though they are not inline, they do make front-end editing easy.1 point
-
That's ultimatly what most people wanted to use there. I mostly used something like this by now "\c\o\m\m\e\n\t-Ymd-His"1 point
-
1 point
-
Thanks very much for this Adrian. This has saved me hours of work today.1 point
-
To make the audit process easy enough, there probably should be something automatic code analysis going. Like sensio insight.1 point
-
I am not sure if all modules or plugins will ever be completely 100% secure. Someone correct me if I am wrong as I am not an authority on security. Can we really say that the vulnerabilities found out in some Wordpress plugins won't be found in Processwire sometime in the future with or without checks when Processwire becomes more of a target like Wordpress currently is? The plugin in question for Wordpress is a big plugin with 100 thousand plus installations and I am sure that as many checks as possible were made with it(but obviously not enough). The way I see it is that bugs happen and mistakes will always happen as long as humans run the show.1 point
-
Hopefully we won't be going to 2.6 without, at least, merging some things from current dev branch to master (2.5). Just saying. New features are one thing, but there are also bugfixes there, as far as I can remember correctly. IMHO minor versions (x.x) should always be stable and contain no known bugs. Unless support for 2.5 is dropped instantly when 2.6 comes out, which I hope we won't be doing -- upgrading from one minor version to another shouldn't be required just to get bugfixes in1 point
-
This is something i'm also missing. And I think most of you don't get what ryanlath means: Sometimes it's just a waste of time to create special "folder" templates just to structure the information in the page tree (especially if they need different icons to distinguish them easier). It would be great to have some sort of pre defined "folder" or "strucure" element that doesn't (necessarily) create an url-slug. Example: I always create a template called "folder" (sometimes even 10+ just for the icons) and on the root of the page tree there are 2 or 3 folders like "meta" (containing legal information, contact...), Data (containing PageTable items), [...]. Those folders wouldn't need their own url-slug but i don't want their contents to "mess up" my page tree. This is just a matter of keeping things easy to navigate (in the backend) rather than grouping information in a semantic way.1 point
-
There are already some posts about this. I remember Soma did some good recommendations. I also remember something about approval. Something to let a module go through some kind of approval check before it becomes downloadable. I will look for those posts later on. Let's stick our coding heads together and make Processwire Modules the safest on the planet.1 point
-
What about modules in processwire? Everything safe? Maybe we need a tag [security-checked] given by an accredited team of PW developers.1 point
-
Hi...just a quick one to let you know that I have this working...rows and columns grow with each new row and column pages or shrink when these are deleted/trashed/hidden/unpublished. I need to do a couple more tests and cleanup the code (remove hard-coded stuff, rename the db table columns to something more generic, e.g. matrix_row and matrix_column, etc) . I also want to make the Fieldtype more configurable - e.g. ability to use a PW selector to find pages to populate rows and column headers (x and y axes). However, not sure if the Fieldtype duplicates what is already available in PageTable? Anyway, here's some screens.. matrix (InputfieldMatrix) db table (FieldtypeMatrix)1 point
-
Small update on this: I will build support for tax classes, stock management and simple reports during Christmas holidays. After that hopefully ready for wider beta testing.1 point
-
Hi kongondo, Thanks for the quick reply and the welcome. I had actually already read the topic that you mention, and this is what prompted my need: I would like to save a "stock" field for each product, but this field would have to be calculated each time a stock movement is saved, and calculating this field is precisely what takes so much time. In the meantime, I continued looking into the problem, and I think that I came up with a solution with the following module: class PagesSum extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Pages Sum', 'version' => 1, 'summary' => 'Adds a $pages->sum($selectorString, $fieldName) function to sum the value of a specific field over a list of pages selected by a selector string.', 'singular' => true, 'autoload' => true ); } public function init() { $this->addHook('Pages::sum', $this, 'sum'); } public function sum($event) { $selectorString = $event->arguments(0); $fieldName = $event->arguments(1); // Find all the pages associated with the selector string $pageFinder = new PageFinder(); $idQuery = $pageFinder->findIDs(new Selectors($selectorString), array('returnQuery' => true)); $idQuery->set('orderby', array()); $idQuery->set('groupby', array()); $idQuery->set('limit', array()); $stmt = $idQuery->execute(); $idArray = $stmt->fetchAll(PDO::FETCH_COLUMN); // If no pages were found, return 0 if (count($idArray) == 0) { $event->return = 0; return; } $idString = implode(',', $idArray); // Get the table name for the given field name $field = $this->fields->get($fieldName); // If no field with this name is found, return 0; if (!$field) { $event->return = 0; return; } $tableName = $field->getTable(); // Run the SUM query $sumQuery = new DatabaseQuerySelect(); $sumQuery->select("SUM(data)"); $sumQuery->from($tableName); $sumQuery->where("pages_id IN ($idString)"); $stmt2 = $sumQuery->execute(); list($total) = $stmt2->fetch(PDO::FETCH_NUM); $event->return = $total; } } In my tests, it is about 60 times quicker to calculate the sum with the function $pages->sum($selectorString, $fieldName) than looping over the pages (for about 12000 pages). I would appreciate any feedback, in case there are any other optimizations to be achieved, or any errors I haven't thought about. And I hope that this might maybe be useful to others too!1 point
-
Thanks. In the current version of the module it will only work with assets uploaded via the admin. That's something in the roadmap for me but I don't have a date I can share right now because I'm really lacking the time at this moment.1 point
-
@ivan not sure I follow $allDescendantsOfEvents = $pages->get('/events/')->find(""); Too many code examples in this thread that makes no sense. You don't want to return ALL descendants to then filter them again by parent etc. In my cases this could return 100k pages it then filters 100 pages from that...1 point
-
1 point
-
Mike, For this example, I'll assume your field is called "images". To get the first image, you would do this: $firstImage = $page->images->first(); To get a numbered index, you would do: $nthImage = $page->images->eq($n); // where $n is a 0-based index Or, of course you can iterate the images too: $n = 0; foreach($page->images as $image) { echo "Image $n - " . $image->url; $n++; }1 point