Leaderboard
Popular Content
Showing content with the highest reputation on 03/13/2015 in all areas
-
Hello there Yesterday we at update AG relaunched the new 1815.ch news portal of Mengis Medien AG. It's a big new portal of a local newspapers here in Wallis Switzerland. That's where the Matterhorn is also It was a thrill to work on this project using ProcessWire. We're still working out some details and adding more stuff in future. There's a lot going on and it has quite lot of traffic. 60k+ pages at the moment. Currently it serves 18k+ articles plus a lot of other data that are just pages. But will grow a lot. The portal has currently around 7k+ user registered. Lots of imports and exports are going on in the background. That mostly are XML feeds or data being uploaded to server. Some news are imported and automated. While they have different teams creating articles apart from the imports of their newspaper also via XML. http://www.1815.ch17 points
-
I know there are benefits and drawbacks to different approaches, so I'll try to explain why PW uses the approach it does, and respond to some of the points above. The approach described as an alternative here is similar to what I've used on other projects, including PW1. I was really looking to come up with something different for PW2. The goal was to make it as absolutely simple as possible for people to add hooks and for people to make methods hookable. I wanted it to be in the background and everywhere, so that you really didn't even have to think about it. It's not designed for ease of consumption by xdebug, I'll give you that. But it is designed for ease of consumption by you and me, which I consider more important. Admittedly I don't use xdebug very much anymore, so designing things for xdebug has not been a priority. When you start a new CMS project, you are in a crowded space, so you have to come up with things that are different. So one of the ways ProcessWire differentiates itself is by making hooks easier to hook into and create than they are in other platforms, and I'd like to keep to that. When it comes to PW's code base, I consider it important to not add complexity purely for sake of static analysis. From my perspective, static analysis is a good thing, and I'm more than happy to let it dictate the direction of comments and what supports the code. But when it starts to dictate the direction of the actual code towards unnecessary complexity/verbosity, less efficiency or reduce the simplicity of the API, then I consider it no longer helpful. If ProcessWire were just a PHP framework and coders in IDEs were the primary audience, then I would feel differently. But for ProcessWire's audience and growth, when I'm confronted either making my IDE happy (and related tools like xdebug), or making the API (or related things like hook system) as simple and as good as they can be, I'm always going to choose what's best for PW's API and systems. My preference is making both happy. But when you are doing something different, existing tools won't always be familiar with it. For something like the hook system, there was definitely a conscious decision to go with what's best for PW and PW users, over what's best for static analysis or xdebug. All the add hook methods are actually handled by just one method: addHook(). The point of the other methods (mentioned below) is to make things simpler for you, and make your code more readable. I prefer verbose method names to boolean and array arguments because they are self describing. think this is a benefit, not a drawback. Use addHook() if you want to add a method to a class that isn't already there. Use addHookProperty() if you want to add a property (rather than a method) to a class. Use addHookBefore() if you want to hook before an existing method (and have the option of modifying arguments sent to it). Use addHookAfter() if you want to hook after an existing method (and have the option of modifying the return value). Regarding the distinction of hooking a class name or an object, this is also meant to be a help to you: The purpose of being able to call a hook on a class name is so that you can hook ALL instances of that class (current and future). The purpose of being able to call a hook on an object is to hook only that single instance of the object. As for ease of finding hooks, this is also something I've tried to make as simple as possible by using a convention that you won't see elsewhere in ProcessWire: 3 underscores prepended to a method. So while you can use CaptainHook, I'm not sure you need to, because you can find all hookable methods in ProcessWire simply by doing a search for 3 underscores "___". A recursive grep is one easy way to accomplish that. Page::render() is actually a very unique case that you won't see elsewhere in PW (that I can think of). Usually I would have just put a method like that directly in a class and have it handle the render from there (or have the method there to call up the PageRender module). But PW started out as fully API driven, where there was no such thing as "render" of anything, to the core. So the ability to "render" anything was seen as something specific to the web context of a CMS. That's ProcessWire now, but its roots are pure CMF. Today, I would likely just put that render() method directly in the Page class. But I also don't see any reason to move what's already working there, as it really makes no difference in how it works. And you can still hook Page::render if you want to, just like it actually did exist in the Page class. Because you can't actually see a Page::render() method in the class, we use phpdoc at the top of the file for it. I would love to make everything hookable, but the reality is that there is a little overhead associated with every hook (in any hook system). So I don't usually make methods hookable unless there is a request for it to be. We started with very few hooks, and now we have quite a lot. But the majority of the hookable methods you see in PW today are the result of people asking for them to be hookable. And luckily, it's very easy to do just that: just append 3 underscores, and you are done. I would answer this pretty much the same way as the Hookability point above. When more granularity is needed somewhere, we add it, and there's lots of examples throughout the core. But it's hard to know where one might need that until it is asked for somewhere specific. When a module like ProcessPageEdit was originally written, I honestly didn't know if anyone would ever want to hook anything in it at all. Over time, it has become more granular, and over more time will become even more so I'm sure, but only when specific needs for granularity/hooks come up. I love flexibility, but I also love efficiency. If everything in ProcessWire was fully granular and hookable PW might be very flexible for someone looking to hook specific things, but it would also be bloated and slow. My preference is to make specific things more granular and hookable when it will solve someone's specific need. Granted, there are plenty of hooks in PW already that nobody is using, but they are generally in places where it makes no difference in terms of efficiency. I'm not suggesting that hooks aren't efficient – there's very little overhead from hooks. It's just that if you multiply a very little overhead over thousands or hundreds of thousands of calls, then it becomes something. Are there any examples? I've tried to cover all potentially useful state changes with hooks, even if they aren't actively used. For instance, see the large set of hookable methods at the bottom of the Pages class. You'll see similarly named methods in any core class that deals with state changes (like Fields and Templates for example). Though it's also possible I've misunderstood what you mean.12 points
-
After having implemented a few different event dispatching systems in my programming carreer, I've still not found the perfect approach, but I've very much given up on overly declarative ways (which do include centralized event management) because at some point, they tend to introduce a level of coding ugliness that's without second. Where, in PW, I can add a hook the moment before it is needed if circumstances are right, a declarative approach often needs loads and loads of repetitive code inside the event hook to make sure its logic is only executed when necessary. Also, declarative event syntax tends to necessitate carrying around much more context, which can be detrimental to memory consumption and performance. Mediator patterns are good in theory, but everyone who has worked on huge event driven projects in C# or Java knows that it's not just a few lines of code more - if you're consequent, you're going to be writing a few times as much code and still find yourself making assumptions about needed interfaces that aren't matched by reality. To me, the biggest issues I have with PW's hook system are ones that can be solved without taking a wholly new approach: Hookability: there are still too many unhookable methods, but that's often because of the next point on my list, which is: Granularity: like with all growing codebases, often code gets written that "gets the job done", yet it does more than one thing at once. Most headaches I get arise from the fact that the hook I need would have to be called somewhere in the middle of an existing method. Also, for debugging reasons, wrapping individual changes inside their own, aptly named hookable method would go a long way; Statefulness: not every state transition has a hook, and if it is there, some information about what the state change(s) entailed may be missing at the next hookable point, or not convenient to get at, and even more, it's often difficult to discern how to revert the state transition. These are usually small things in the scale of PW (and happen far less than in other frameworks I've worked with) as a whole but will pop up every so often as the codebase evolves and grows. No event system will catch that on its own either; I was about to write "hook execution order" before I felt a murky memory tickle the back of my mind and decided to take a look to make sure - lo and behold, hook priority has already been there for years. Yay, Ryan! This is no criticism on PW btw., just a reflection of what points keep popping up. Like I wrote, these are the same things that come up in every big and growing software project. I'm very much with owzim that the only way around debugging madness is granularity. No event system will cure you of memory exhaustion or eye soreness when the backtraces keep growing and the objects to inspect are deeply nested. Once runkit_method_add or a similar mechanism becomes stable, it might make sense for debugging purposes to (optionally) augment the Wire base class (or an event manager stand-in singleton) with static hook closure methods following a fixed naming theme that a debugger can look at, which would alleviate one of the main issues in the OP.7 points
-
Ryan, thanks for pointing me in the exact direction I needed to go! The PW version was not the issue, as I was using 2.5.21 dev. The file you linked to (Fields.php) was the exact source of the memory exhaustion, specifically on a line (caught in the trace too) inside the slow method: if($numPages <= 200 || $hasDeletePageField) { // not many pages to operate on, OR fieldtype has a custom deletePageField method, // so use verbose/slow method to delete the field from pages $items = $this->wire('pages')->find($selector); // << the problematic line, since I have 2.3million pages! //iterate through items etc } The test for the slower method was proving true because of $numPages, which is defined as $numPages = $this->getNumPages($field, array('template' => $template)); which calculates the number of pages which has the field set. So since the field was empty in all pages, numpages was turning out to be zero.I set the slow delete condition to 'false' temporarily, and was able to delete the field via admin in a heartbeat. Since the actual process of page-by-page field deletion doesn't make use of numPages at all, I'm thinking maybe it should be changed to include all pages of the template? Unless I'm missing some other use for it. In any case, thank you so much for the reply, sorted me right out.6 points
-
A small addition to kongondos example: If you only need to get the count, you should use $pages->count("selector") because of performance reasons. The count method does not load the page objects.4 points
-
i don't understand most of what you are talking about - BUT: i understand most of what i am doing with processwire thats what i love about processwire! you don't "see" things that you don't understand and therefore don't need to see. that starts with the admin-interface treeview and continues when you start looking to the file system and furthermore into the code. i just wanted to point out that for a non-professional coder like me these are really important benefits! i like the way PW addresses also beginners and at the same time makes it possible to dig deeper into it if you want to and if you are ready! not before. that said from someone who has created his first hooks some days ago ps: of course i also love discussions like this one on the forum reading about things that i can maybe think of some day.....3 points
-
3 points
-
I just went through trying to install MobileDetect module and ran into the same issues. As far as I can see, It cannot be installed in the normal way, not even using Modules Manager (I tried). I believe the individual would have to follow the explicit instructions to "Clone the module and place MobileDetect in your site/modules/ directory" and then know how to initialize and update the submodule. Error handling If you get the following error message: Compile Error: require_once(): Failed opening required 'lib/Mobile_Detect.php' (include_path='.:/usr/local/Cellar/php55/5.5.16/lib/php') (line 57 of /path/to/site/modules/MobileDetect/MobileDetect.module) you forgot to initialize and update the submodule. (The library is included as an git submodule so I can easily update.) Just run git submodule init git submodule update and everything should work as expected. Anything else won't work and I know I don't have a clue how to work through the process of the git initialize and update. I guess someone would have to read up on how that works or maybe the author of the module can provide the missing installation instructions. What I'm trying to say is that everyone doesn't know git. This problem is not a strictly PW issue. I read through the thread and he had the install working. Edit: For reference, Here is the documentation talking about git init and git update http://git-scm.com/docs/git-submodule3 points
-
You are absolutely right. Either that, or the find() that locates those pages should only include the pages that have a value set. I will go in and update this now. Thank you for going into the detail you did here, as I had not considered that issue before so this is a big help.3 points
-
I just have to chime in with nothing helpful other than to say how thrilled I am to see this. This is going to be such a fantastic tool for content creators.3 points
-
The maximum function nesting thing reeks of recursion. Maybe one of your widgets tries to render itself or some other page that also has this widget? Perhaps inside a prepended/appended file? Is _main.inc auto-appended?3 points
-
Update: version 0.0.3 Updated original post. Now in modules directory: Option to allow Markup in menu items as per this request (superusers only) [note: although values are sanitized via HTML Purifier, it is your responsibility to ensure correct HTML input; also, if you previously allowed HTML markup but the menu was subsequently edited by non-superusers, your HTML will be stripped off] Added more options to MarkupMenuBuilder render() method - first, last classes, etc.(see Read Me) and... Added/enhanced wrapper_list_type and list_type options. The former allows you to specify menu items outer wrapper tag, e.g. <ol>, <div>, <nav>, etc....The latter allows you to specify alternatives to <li>, e.g. <span>. Note, if no list_type is specified and you override the default by 'list_type' => '' in your options, then menu items css classes/IDs are applied to the <a> tag instead. Updated code to ensure menu settings saved by superusers remain even for non-superusers (e.g. menu maxLevels, selectable pages, etc.) Note: Had an extra jquery.asmselect-mb.js in the root folder. I have deleted this in the repository. Note, it seems PageAutocomplete will not allow non-superusers to select pages unless they have a page-edit permission as well. Could somebody confirm/clarify? Thanks.3 points
-
By posts I'll assume you mean pages....What you want is to count the number of pages created by the specified author, hence you want to use created_users_id in your selector. Below author can be an object or an ID $cnt = $pages->find("template=foo, created_users_id=$author"); //find by current user $cnt = $pages->find("created_users_id=$user");//you can also get the user first... https://processwire.com/talk/topic/6423-all-items-from-member-on-member-page/ https://processwire.com/talk/topic/7403-module-blog/?p=857802 points
-
Hi lindquist, That's a good solution you've come up with. If you want to provide an API variable for your object, here's an example, pretty easy like everything in ProcessWire: // This must be inside an autoload module public function ready() { $this->wire('calendar', new Calendar()); } // Or, if you're Calendar module is autoloaded, make the same instance available as API variable public function ready() { $this->wire('calendar', $this); }2 points
-
ooops Wordpress has done it again...actually yoast.. Yoast WordPress SEO Plugin Vulnerable To Hackers2 points
-
A bit OT, but if you can plan the languages hirarchy right from the start of a new site, you can do it this way: enable languages support set Title / Label of the default language to your desired none english native language, (e.g. 'Deutsch' (German)) drop in the none english language pack (for admin backend) into the default language, (e.g. german langpack) add a new language to it and drop in a language pack for any none english language or simply don't drop in a language pack to get the english version (but not as the default one!) As a nice sideeffect every new user in your system gets the native language per default without have it to select from the list. So, yes, this is no solution if you once have set it up and need to switch the default language afterwards, but just want to note it.2 points
-
Multilangual descriptions can be turned of for both images and files. It is a setting in the (Advanced) Input tab. I don't know which ProcessWire version introduced this but it has been around lately.2 points
-
OK...on my TODO. I have expanded it to other features, not just the selectors. See this also. What are your thoughts about controlling ability to delete menus too? Any other controls I am missing? Thanks.2 points
-
2 points
-
Interesting discussion! For me (as a developer), the advantages of ProcessWire's hooking system overweight the issues you mentioned. I agree, it's sometimes harder to find the relevant piece of code, because it gets added dynamically with hooks. Debugging is definitely harder too. But in my opinion you can never achieve the same flexibility with events. For example, how would you handle the beforeHooks, which are executed before the "real" method is invoked? How would you modify the passed arguments? Also the afterHook can modify the return value. It's so powerful and easy to do - just add those three little underscores and you can use this power in your own Wire-derived classes. I like2 points
-
Interesting topic, thanks for your efforts accumulating all those infos. Although I've yet to investigate further the alternatives you are proposing, there are a couple of things that come to my mind regarding this: When it comes to debugging hooked methods, I totally feel you. It can make you pull your hair sometimes. But the thing is, you can either have massive flexibility and power in this case, and then have to trade in some other things. It's like with loosely types languages vs. strongly typed languages. Loosely typed languages give you great power, but it can be a pain, for let's say a Java developer. Two things I've used heavily in the past half year or so, that saved me a lot from going bald: The ChromePhpLogger module by soma, it's not an ideal debugging tool on it's own, but certainly a necessary one in my toolbox Unit tests: I've learned to split my logic into pieces as tiny as possible. During development I only test against those tiny pieces. If the pieces are working on their own, the big picture code will mostly work out of the box. Debugging also only happens on the tiny piece level and makes massive backtrace debugging madness almost vanish2 points
-
Menu Builder As of 29 December 2017 ProcessWire versions earlier than 3.x are not supported Modules Directory Project Page Read Me (How to install, use, etc..) For highly customisable menus, please see this post. If you want a navigation that mirrors your ProcessWire page tree, the system allows you to easily create recursive menus using either vanilla PHP or Soma's great MarkupSimpleNavigation. In some cases, however, you may wish to create menus that: 1. Do not mirror you site's page tree (hirarchies and ancestry); and 2. You can add custom links (external to your site) to. That is primarily where Menu Builder comes in. It is also helpful if you: 3. Prefer creating menus via drag and drop 4. Have a need for menus (or other listings) that will be changing regularly or that you want to allow your admin users to edit. The issue of custom menus is not new here in the forums. The difference is that this module allows you to easily create such menus via drag and drop in the Admin. Actually, you can even use it to just create some list if you wanted to. In the backend, the module uses the jQueryUI plugin nestedSortable by Manuele J Sarfatti for the drag and drop and is inspired in part by the WP Custom Menu feature. Please read the Read Me completely before using this module. For Complex or highly-customised menus, it is recommended to use the getMenuItems() method as detailed in this post. Features Ability to create menus that do not mirror your ProcessWire Page Tree hierarchy/structure Menus can contain both ProcessWire pages and custom links Create menu hierarchies and nesting via drag and drop Easily add CSS IDs and Classes to each menu item on creating the menu items (both custom and from ProcessWire pages) or post creation. Optionally set custom links to open in a new tab Change menu item titles built from ProcessWire pages (without affecting the original page). E.g. if you have a page titled 'About Us' but you want the menu item title to be 'About' Readily view the structure and settings for each menu item Menus stored as pages (note: just the menu, not the items!) Menu items stored as JSON in a field in the menu pages (empty values not stored) Add menu items from ProcessWire pages using page fields (option to choose between PageAutocomplete and AsmSelect [default]) or a Selector (e.g. template=basic-page, limit=20, sort=title). For page fields, you can specify a selector to return only those specified pages for selection in the page field (i.e. asm and autocomplete) For superusers, optionally allow markup in your menu titles, e.g. <span>About</span> Menu settings for nestedSortable - e.g. maxLevels (limit nesting levels) Advanced features (e.g. add pages via selector, menu settings) currently permissible to superadmins only (may change to be permission-based) Delete single or all menu items without deleting the menu itself Lock down menus for editing Highly configurable MarkupMenuBuilder - e.g. can pass menu id, title, name or array to render(); Passing an array means you can conditionally manipulate it before rendering, e.g. make certain menu branches visible only to certain users [the code is up to you!] Optionally grab menu items only (as a Menu object WireArray or a normal array) and use your own code to create custom highly complex menus to meet any need. More... In the backend, ProcessMenuBuilder does the menu creation. For the frontend, menus are displayed using MarkupMenuBuilder. Credits In this module's infancy (way back!), I wanted to know more about ProcessWire modules as well as improve my PHP skills. As they say, what better way to learn than to actually create something? So, I developed this module (instead of writing PW tutorials as promised, tsk, tsk, naughty, naughty!) in my own summer of code . Props to Wanze, Soma, Pete, Antti and Ryan whose modules I studied (read copied ) to help in my module development and to Teppo for his wonderful write-up on the "Anatomy of fields in ProcessWire" that vastly improved my knowledge and understanding of how PW works. Diogo and marcus for idea about using pages (rather than a custom db table), onjegolders for his helpful UI comments, Martijn Geerts, OrganizedFellow, dazzyweb and Mike Anthony for 'pushing me' to complete this module and netcarver for help with the code. Screens1 point
-
Is my 100th post I wanted to do something special. I edited a video, hope you like it Just for fun Edited: Now with subtitles1 point
-
Inputfield And Fieldtype ImageFocusArea requires ProcessWire 2.5.6 or later This Inputfield makes it possible to select the important part of the image and use this area for different cropping options. This module is not a replacement for the existing Thumbnails module, though depending on your need it probably could replace it in many cases. I think a more flexible cropping approach than the existing Thumbnails module is useful especially when using the new html <picture> and you don't want the editor to define multiple thumbnails. Usage Create a new Inputfield ImageFocusArea and add it to the desired template. Edit a page with this template and add an image to the new field. You will see a link "Add Image Focusarea". Click the link and you will see a popup with a cropping tool similar to the Thumbnails module. Select the important part of the image, click "apply" and save the page. By default the Field hooks into Pageimage::size and automatically populates the cropping option with percentages of the center of the selected focusarea. You can always override this behaviour by calling $image->size with a different cropping option (e.g. $image->size(100,100,array('cropping'=>'center'))). The module introduces 3 new cropping options: align: This is the default if you do not override it with another cropping option. When resizing a image the module only adjusts the alignment of the crop. You will get the most zoomed-out result of these options. inside: Only parts inside of the selected area are used in the resulting image. You will get the most zoomed-in result of these options. outside: The resized image will contain the whole selected area. The surrounding imagearea will be used to reach the targetsize. This is also true for upscaling=false. Upscaling will only happen if the source image was smaller then the targetsize. API usage examples // here we force the old/usual 'center' mode: echo "<img src='{$page->image->size(200,200,array('cropping'=>'center'))}' />"; // by default if you did not define a cropping option, the cropping option gets automatically populated // Both calls will result in the same image: echo "<img src='{$page->image->size(200,200)}' />"; echo "<img src='{$page->image->size(200,200, array('cropping'=>'align'))}' />"; // the resulting image will be the center area of the selected focusarea echo "<img src='{$page->image->size(200,200, array('cropping'=>'inside'))}' />"; // to get an image with exactly the same ratio as the focusarea use width()/height() instead of a size() echo "<img src='{$page->image->width(200, array('cropping'=>'inside'))}' />"; echo "<img src='{$page->image->height(200, array('cropping'=>'inside'))}' />"; // the whole selected area will be part of the image, the surrounding imagearea will only be used to reach the targetsize echo "<img src='{$page->image->size(200,200, array('cropping'=>'outside'))}' />"; Flexible CSS Background Images Additionally you can access a new property cssBackgroundPosition, which could be useful for frontend responsive images. The visual result is similar to the cropping='align' mode, but depending on the size and postion of the focusArea and your images source and target size your mileage may vary. This property is intended to be used together with background-size: cover;. It is important that the background-image has the same ratio as the original image! <style> .cssimg{ background-size: cover; width:200px; height: 200px; } </style> <div class="cssimg" style="background-position: <?= $image->cssBackgroundPosition ?>; background-image: url(<?= $image->url ?>); "></div> Downloadhttps://github.com/phlppschrr/ImageFocusArea remember, this modules requires ProcessWire 2.5.6 or later There are still known bugs with upscaling=false, but I am not sure if it is a bug of this module or a ProcessWire bug. (fixed in ProcessWire 2.5.6) Thanks to Ryan and especially Horst for all the new great API additions for Pageimage und ImageSizer which made this module possible. This is my first module. If you notice any problems or unexpected behaviour post here or fill an issue on github. I am open to all suggestions. Do you think the cropping option names (align, inside, outside) are descriptive enough? Any better ideas? -- Edit: Renamed the Module to ImageFocusArea and updated the github link Edit 2: Reformatted this post and added some additional information.1 point
-
-------------------------------------------------------------------------------------------------------------------------------- for PW 3.0+ please follow this link! -------------------------------------------------------------------------------------------------------------------------------- Croppable Image Module for PW >= 2.5.11 and PW <= 2.7.3 Version 0.8.3 alpha Hey, today I can announce an early (alpha) release of CroppableImage, what was forked from Anttis Thumbnails module. Until now there was a lot of work done by owzim, Martijn Geerts and me. We have solved the issues regarding the list from here: The modules are bundled together so that you only can and have to use FieldtypeCroppableImage for install, uninstall & configure. It uses new naming scheme that was introduced with PW 2.5.0 that supports suffixes. The complete image rendering is delegated to the core ImageSizer, or to any optional hooked in rendering engine. Template-settings are now fully supported, including removing variations when settings have changed. It fully respects settings for upscaling. If upscaling is set to false, you cannot select rectangles smaller than the crop setting. We implemented these enhancements: The GridView now is very nice and compact, and also benefits from the lately introduced setting for $config->adminThumbOptions. Permanent storage of the crop coordinates, quality and sharpening settings are now implemented native. No need to use PiM for this anymore. The usage/display of the Quality and Sharpening DropDown-Selects can be globally disabled/allowed in the modules Configpage. (additionally to that a setting on a 'per field base' is planned.) And the most wanted feature by the community: It gives back a pageimage and not the URL-string. This way you can use it like this: // get the first image instance of crop setting 'portrait' $image = $page->images->first()->getCrop('portrait'); You can further use every pageimage property like 'url', 'description', 'width' & 'height' with it: // get the first image instance of crop setting 'portrait' $image = $page->images->first()->getCrop('portrait'); echo "<img src='{$image->url}' alt='{$image->description}' />"; And you can proceed further image rendering with it: // get the first image instance of crop setting 'portrait' and proceed a resize with imagesizer $image = $page->images->first()->getCrop('portrait'); $thumb = $image->width(200); // or like this: $thumb = $page->images->first()->getCrop('portrait')->width(200); // and if you have installed Pia, you can use it here too: $thumb = $page->images->first()->getCrop('portrait')->crop("square=120"); The only downside with this is that when you (as the site developer) have enabled the usage of DropDown-Selects in the images editor, you do not know the values the editors have chosen for the images. As a workaround for this you can use the getCrop() method with a second param. This is a PW selector string. It can contain as many of the known pageimage options like 'quality', 'sharpening', 'cropping', etc, as you need, but none of them is required. But required is at least one setting for 'width' or 'height': $image = $page->images->first()->getCrop('portrait', "width=200"); $image = $page->images->first()->getCrop('portrait', "width=200, height=200, quality=80"); $image = $page->images->first()->getCrop('portrait', "height=400, sharpening=medium, quality=75"); . . You can get the module from GitHub: https://github.com/horst-n/CroppableImage (Better Docs are coming soon) Screenshots Related Infos A good setting in site/config.php for the AdminThumbs are: (height=>200 and scale=>0.5 !) $config->adminThumbOptions = array( 'width' => 0, 'height' => 200, 'scale' => 0.5, 'imageSizer' => array( 'upscaling' => false, 'cropping' => true, 'autoRotation' => true, 'sharpening' => 'soft', 'quality' => 90, 'suffix' => array(), ) );1 point
-
I opened an issue in the Mobile Detect github space regarding how this module installs. Reference https://github.com/justonestep/processwire-mobiledetect/issues/11 point
-
Me neither. But recently I spoke with a few local designers/developers to whom it did matter. Then came along our client so it was a nobrainer because I could learn something along the way. Will text you to set a small meeting up.1 point
-
What apeisa said, but that error makes me think you've got something incorrect in your Details > Select Options textarea because $value is not being set. The only way I can make that happen is to have more than one ":=" on a row. Of course the module should have a better check on this, but I still think you might have something incorrectly configured. EDIT - I see you found your error1 point
-
1 point
-
I hope there are never that many PW modules for any one general feature such as a gallery. With PW this should never come to pass; WP only has that many because of course they're all plug-and-play with a million minute options for the back- and front-end to choose from, like positioning or color of captions... most of which are, most of the time, for most people, wholly unnecessary. PW should refrain from jumping on that bandwagon. Given the power of PW out of the box there probably will never be nearly as many modules in the directory as there are WP plugins, and that is a beautiful thing.1 point
-
We've now added cache busting for all assets in our boileplate. This means that in production, if an asset has been added to a manifest in the assets/ folder, your site will now serve an MD5'd version of the file. i.e. style.css -> style-18925h5bsdfsdfn.css No worries about appending query strings or force refreshing to get the latest asset, it's all done for you. Use of the manifest is optional. If an asset is not being rev'd in the manifest, it will be served with the filename you provide. e.g.: <!-- if this asset is not in the manifest, it will be served as assets/img/logo.svg --> <link rel="logo" type="image/svg" href="http://<?= $config->httpHost . $this->assets('img/logo.svg') ?>"/> <!-- if this asset IS in the manifest, in production it will be served as assets/css/style-9n183he.css --> <link rel="stylesheet" type="text/css" href="<?= $this->assets('css/style.css') ?>" > For an asset to be eligible for rev'ing, it must be accessed through the assets helper in views / templates: $this->assets('path/to/my/asset.ext') This is used best in conjunction with some sort of task automation, for which we have a Yeoman generator which generates a project with a Gulpfile that handles all the rev'ing of assets without any additional work for you: https://github.com/fixate/generator-fixate-pw (and more specifically, the gulpfile: https://github.com/fixate/generator-fixate-pw/blob/master/app/templates/_gulpfile.coffee) To create the manifest, you can run the following from the command line: $ gulp build You're now ready to deploy with your cache busted assets. Assets that are being rev'd by Gulp are css, js, images, and fonts (even handles rewriting paths in your css). Happy cache busting!1 point
-
(This is just my opinion and may not be 100% technically accurate, but here it goes) You shouldn't have any issues installing and using processwire, and based on your posts, the only way I can recommend for you to get a clean install is to completely sequester your PW install from all other things on your hosting; so in short: 1.) Create a subdomain from cpanel, and make sure it uses a folder not within any other currently used folder (e.g. not a folder inside your public_html) 2.) setup a new clean database only for PW (for example using mysql database wizard) 3.) upload latest dev of PW into your new subdomain folder 4.) access your subdomain from mysubdomain.mysite.com and run the install post back any errors you see here1 point
-
Indeed, though after some research, they added support for $this in PHP 5.4, which is why it works on my local server (I have PHP 5.4.7).1 point
-
Yes and thanks for this, because that's help me. What I want is that widgets (partials) need to be last in processing - and - widget can be any kind of content type (template). Also, I know that all this can be done using some checks (function) and with known path to some partial (eg. $config->paths->templates . "banner.php" ) - but I want flexible principle inside main layout template file, and use at least possible logic for that job (later some new partials can be easily added to some new pages - without coding). And @ Jan Romer, in my case _main.php is appended, and because I neglected that very important part - I get website loading problem. Finally I solve my problem when added 'appendFile'=>null to render() options. // _main.php // main layout template file // appended $widgets = $page->widgets; if(!$widgets || !count($widgets)) $widgets = $homepage->widgets; foreach($widgets as $widget) { echo $widget->render('', ['appendFile'=>null]); //'appendFile'=>null } With this I get desired result, very simple can add different content type widgets (partials, banners) to different pages. Best regards and thanks!1 point
-
Yep, If I remember correctly, you can't refer to "$this" in a closure. But you could use wire('session') to get the session object there.1 point
-
I never liked programs/software translated to Dutch. So personally I wouldn't use the translated ProcessWire. On the other hand, I do think it's good for the ProcessWire project. Could you phone me so we can work something out?1 point
-
The problem is most probably the $this->user->isSelena() function. I understand the confusion, since $this->user->isSuperuser() gives the impression that you can use any user name, but it's not the case. isSuperuser() is a built-in method of the User class (you can find it on the cheatsheet under $user / User methods). If you want to allow only a specific user with the username "selina", you would do if (!$this->user->name === 'selina') This should hopefully do the trick. You should also add a semi-colon after the }) on the third line from the bottom, or you'll get another error1 point
-
No one has complained about issues, 1.0.0 it is. Merged into master, submitted to the directory and updated original post. I might not have the necessary time to tackle the road map for now, but if issues arise, I surely can fix them.1 point
-
Yep - I see that it totally works with PW tables. Thanks for looking into an option for non PW tables. I am actually wondering if you might be able to do something like: $page->selectextoption->db_field_name and be able to return the value from any field (column) for the row that contains the selected integer ID value? This could work with both PW and non PW tables. Some examples of what you could return with this. PW fields table: $page->selectextoption->id = 1 $page->selectextoption->name = title $page->selectextoption->label = Title $page->selectextoption->flags = 13 a non PW table (maybe a list of country codes): $page->selectextoption->num_code = 276 $page->selectextoption->iso3 = DEU $page->selectextoption->name = Germany I think this would be much more powerful than just returning the value and label fields. I think it might also be nice to be able to magically return the selected value and label without knowing what the fields are, so: $page->selectextoption = 1 $page->selectextoption->selectedLabel = Title (assuming the field I chose for the label was the title field) Of course you can't use "Label" in this last example because "Label" is a field name in some PW tables, hence my use of "selectedLabel", but there might be a better option. Does that make sense? Thanks for your hard work on this - it's going to be very useful!1 point
-
I just committed big refactoring to Fredi, which fixes all the known bugs and simplifies a code a lot. I haven't tested this yet on other pw versions than latest dev, so be careful when testing. It "should" work pretty universally, since now it uses ProcessPageEdit instead of own custom processes. So image/file uploads and reordering (tested) and repeaters (not tested...) should work also.1 point
-
Normally using $this is for modules only. Inside templates you should use wire() methods you can also get the object via the $event var. wire()->addHookBefore('Session::logout', null, 'logoutNoCookie'); function logoutNoCookie(HookEvent $event) { $hookObject = $event->object; } See also http://processwire.com/apigen/class-HookEvent.html https://processwire.com/talk/topic/4701-add-hook-in-a-template/ https://processwire.com/api/hooks/#all_or_one http://www.flamingruby.com/blog/using-hooks-to-alter-default-behavior-of-processwire/ Cheers1 point
-
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 ....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
-
adrian, yeah, but the massive amount of plugins to do great stuff out of the box is one of the key points pro-WP-people make. If you can't trust them plugins, there are not many pro arguments left.1 point
-
To be fair to WP, this is not a vulnerability with the core code, but rather an issue with a 3rd party plugin: http://codecanyon.net/item/slider-revolution-responsive-wordpress-plugin/2751380 I haven't read the details of the issue, so perhaps some stronger core code might have prevented this, but it doesn't matter how good the core code is, a plugin/module can be a vector for security issues in even the most secure core code.1 point
-
As for your wish request. It is already possible to track changes, what -> old -> new value. $user->setTrackChanges(true); wire()->addHookAfter("User::changed", null, function($event){ $what = $event->arguments("what"); $old = $event->arguments("old"); $new = $event->arguments("new"); echo "changed: " . $what . " - " . $old . " -> " . $new; });1 point
-
Hi Marco, In ElasticSearch.module can you try changing the below function (around line 190): protected function getPageTypeAsContent($value) { return $this->getAllContentForPage($value); } to: protected function getPageTypeAsContent($value) { return $value->title; } Let me know if that gets rid of the nesting issue, and if search results are affected. Thanks1 point
-
Here is a cleaner function based approach to this: http://processwire.com/talk/topic/5397-assigning-fields-to-repeaters-with-the-api/?p=521231 point
-
I've never come across a client that didn't prefer a rich text editor to the alternatives. The reality is, they like RTEs because it's something they are already familiar with and it's easy for them to use. So I think a better goal is to give them what they want, but place limits upon it so that it can't produce a mess. Just because RTEs+clients can create a mess doesn't mean we have to let them do it. Both our TinyMCE and CKEditor rich text inputfields come very much restrained and prevent the client from creating a mess. CKEditor4 and it's ACF (advanced content filter) seem particularly adept at solving this problem. If you can convince a client to use an LML (Markdown, etc.) or some method of creating content in blocks, then that's fine. But once the next guy comes around showing them "look what you can do in my CMS–it's like using Word", you may be at a disadvantage. Other factors to consider: 1) content maintained by blocks may be significantly less portable through future CMS changes, web service/syndication feeds and such; 2) it may be more difficult to maintain site-wide consistency with the designer's original vision if a site's main content area is a mashup of content blocks. Personally, I would avoid trying to pursue a blocks strategy for most content editors, whether in a CMS that is built around the concept, or via trying to build everything around Hanna Codes. Instead, let the designer do their job and determine consistent and well thought placements for photo galleries, navigation, etc. I see Hanna Code as being better for the exceptions of needing something somewhere, and not something that editors should have to keep as part of their vocabulary.1 point