Leaderboard
Popular Content
Showing content with the highest reputation on 04/22/2019 in all areas
-
Frontend built in UIkit 3. Backend is a modified version of what I did for HealthCARE Express. I am using the top level pages to hold information only, so no design rows as children. Children are always sub pages. The page builder area is under a settings page that has children for things like the navigation menus, and themes. (The themes hold the page layouts, color schemes and uikit and theme components.) Here is a video showing adding an intro section to a basic page. (Basic page has an inner page heading row already added.) . Instead of adding a text item, I could have added a code item and echoed text tied to the basic page. I may also make a hook for auto creating the layout page to save that step, and add a link on the front end for adding new rows without needing to visit the backend settings area. I put menus under settings so you can design the top menus, main menu, and footer column menus from one spot, and every widget that reads them gets set at one time. You can also control if they open in the same or new windows, and add off site links this way. I just feel like depending on only hidden and non hidden root pages is not enough. Also, an incoming theme can default to reading a menu named a certain way. Menus are primarily set via selector, so you do not need to edit it them every time you add a service for example, like if you wanted to have a service menu in wordpress. So if I do a page template for a Service, there can still be a rich text box and image field for that service attached to the page template, so there is no way for someone to mess up the design just to edit, and to reduce confusion, but if you want to use the page builder to add rows, you can dig into that settings page and edit the rows for the page. I also have front end editing turned on so you can double click almost anything to edit, and added a small drop down at the top right of the page that loops through all rows on your page so you have a shortcut to edit just that row from the backend. The page builder rows are matched by path. ie. /about/ would match /settings/themes/selectedtheme/bypage/about/ and might match /settings/themes/selectedtheme/bytemplate/basic-page/ also, if the about page was a basic page template. Everything will match the sitewide folder. This type of thing lets you do things like add a call to action on a group of pages by adding that row to the template instead of the page. Or add a css file or javascript file to a group or sitewide. The layouts template holds the layout types, like per page or per template, and layout types can have children like sections, containers, grids, cells, images, text, accordions, php or html code, etc. I have also played with doing a page group layout type so you can group a few pages together and add a row or code snippet to those as well. This output method does not require php eval. I actually just start an output buffer and include. That gets added to a snippet array variable that I can sort and edit until the very end when it is time to output. The first level in the array is 8 slots that works as placeholders, and then each of those 8 slots holds the rows or code snippets for that placeholder. ie. before html, head, body-top, body-header, body-main, body-footer, body-bottom, after html are the default placements code can target. The second level also has weights. In addition to targeting a placeholder, a section will also have a priority drop down of highest, high, medium, low, lowest. That way a bottom call to action can be tied to the body-main spot as low priority, and no matter if it is added to the template, page group, page or sitewide, it will always sink to the bottom. Plugins used: Inputfield Ace Extended, MarkInPageTree, Breadcrumb Dropdowns, Prev/Next Tabs (for switch from row to row), Hanna Code The page builder has almost all of UIkit added so you can add a grid to a section and set the child width by drop downs, or you can use drop downs to set them on the child cell pages individually. The cell pages would allow you to add heading, text, images, accordions, etc. If you add a text item to a cell for example, the first tab is content for the rich text editor, and the second tab is design for things like text alignment per device. (So you can say center on mobile or left align on desktop without writing any code!) . The advanced tab holds an id over ride, extra classes box, and a javascript and css box that will minify on page save and be included into your website. This allows any item to add advanced css or js in a portable way. I will attach some screenshots! https://www.medpracticesuccess.com/4 points
-
Related: https://github.com/processwire/processwire-requests/issues/2683 points
-
2 points
-
If you're brave enough, you could try to clone the admin search module: /wire/modules/Process/ProcessPageSearch/ rename it and put it under site/modules/ - you would have to alter rights (the admin search requires edit-rights) and certainly some other stuff. The way I did it once, is: http://www.runningcoder.org/jquerytypeahead/ - for autosuggest / type-ahead functionality $(document).ready(function () { $.typeahead({ input: '#q', hint: true, maxItem: 20, order: "asc", cache: 'localStorage', ttl: 3600000, // 1 hour display: ["title", "vertec", "year", "project_desc_short"], source: { url: 'https://prototypes.domain.com/project-abc/autocomplete/json/' // Ajax request to get JSON from the action url }, callback: { onResult: function (node, query, result, resultCount, resultCountPerGroup) { $('#resultCountIndicator').text(resultCount + " hits"); }, onCancel: function (node, event) { $('#resultCountIndicator').text(''); }, // Redirect to url after clicking or pressing enter onClickAfter: function () { var keyword = $('#q').val(); window.open( 'https://prototypes.domain.com/project-abc/search-results/?search-type=text&keyword=' + keyword, '_blank' ); } } }); }); To optimize performance, I created a hook or cron job: Store all the searchable fields in JSON format in one special PW page. That's the autocomplete/json above in source url. This special template has URL segments enabled: <?php namespace ProcessWire; ini_set('max_execution_time', 600); // 10 minutes ini_set('memory_limit', '256M'); // update process triggered (here it's done manually - it's just a normal link in the admin dashboard) if ($input->urlSegment1 === 'update') { $selector = "parent=1041, has_parent!=2, include=all"; $matches = $pages->findMany($selector); foreach ($matches as $match) { $result = array( "title" => $match->title, "year" => $match->year, "client_name" => $match->client_name, "vertec" => $match->vertec, "project_desc_short" => htmlspecialchars_decode(strip_tags($match->project_desc_short)), ); $results[] = $result; } header("Content-type: text/html; charset=UTF-8"); echo "<p>New autocomplete JSON is being generated...</p>"; $content = json_encode($results); $page->setOutputFormatting(false); $page->autocomplete_json = json_encode($results); $page->save(); $resCount = count($results); $url = $page->url . "json"; echo "<p>et puis voilà: $resCount projects found in <a href='$url' target='_blank'>JSON</a></p>"; } // just output the generated JSON to the frontend (JS) if ($input->urlSegment1 === 'json') { header("Content-type: application/json; charset=UTF-8"); echo $page->autocomplete_json; } In other words, I generate a JSON that holds all the infos I need. I only query PW directly, when something has been updated. The fullscreen thingy you mention is just plain CSS, I guess.2 points
-
Page Field Edit Links GitHub: https://github.com/thetuningspoon/AdminPageFieldEditLinks Direct Download: https://github.com/thetuningspoon/AdminPageFieldEditLinks/archive/master.zip This module is based on--and is the successor to--Macrura's AdminPageSelectEditLinks (https://processwire.com/talk/topic/8477-adminpageselecteditlinks-module-for-enabling-edit-links-on-multipage-selects/) Page Field Edit Links adds modal editing capability to ProcessWire's Page fields in the admin editor, allowing editors to easily view and edit the content of any page(s) that have been selected, as well as create new pages without leaving the current screen. Edit links are updated in real time when new pages are added to the field. Compatible with all available types of Inputfields including Select, SelectMultiple, Checkboxes, Radios, AsmSelect, PageListSelect, PageListSelectMultiple, and PageAutocomplete.1 point
-
Another proof-of-concept module: JsonNativeField Leverages MySQL >= 5.7.8's native JSON column type for key-value storage. This gives us the opportunity to store arbitrary (textual) fields in the database and allows us to search for them with plain subfield selector syntax, including wildcard operators. Possible applications are storing submitted form data or adding user-defined properties to their profile. Currently, the module is still really, really alpha, but I wanted to get input early on. Let me know what you think. Download from GitHub. Here are a few screenshots for anybody interested but unable to try for themselves: 1. First page with json field and custom subfields: 2. Second page with json field and custom subfields: 3. Searching through all subfields in the json field: 4. Searching only in a specific subfield: The interface is really rather crude still. The "delete" buttons only work after saving (have to attach listeners to the newly created entries yet), and I've got to straighten out supported operators for Lister to pick up. I'll see if I find some time tomorrow to work on these issues and brush up the visual side a bit.1 point
-
I run a cpanel server in AWS on their cpanel cloudlinux image. I turn on the nightly backup option in cpanel that stores versioned backups for 7 days. If a client gets hacked, I can roll back 7 days with only one versioned backup set. I have the default ssd for the websites and attached a regular magnetic hard drive for cheaper backup storage for the nightly backups. That config doesnt support offsite s3 upload, so I tell aws to do a nightly snapshot of my disks and keep them for 5 days. This also saves me bandwith since those don't count against you. Versioned backups takes 15 min compared to 4 hours or more if you copy every file. cpanel does auto ssl and has a file browser that allows you to upload a zip file of the website, and decompress by right clicking it. Pretty handy. I do not like using cheap client hosting as it is never setup well. My php settings as far as ram and timeout scripts can use are better. I also have a large mysql cache.1 point
-
1 point
-
public function ready() { $this->pages->addHookAfter('added', function ($event) { $p = $event->arguments[0]; if ($p->template->name === "order") { // accessing page reference fields here doesn't work } }); } You forgot to check for the template name.1 point
-
Hello @kkalgidim, if you already use jQuery, I also can recommend jQuery Typeahead by Running Coder. I wrote a tutorial for a autocomplete search function with this plugin: It is basically the same like the code by @dragan, with a little more information. Of course you could use any typeahead plugin or service you want and build a nice search function with ProcesWire. All you have to do is prepare the search results in the required format of the plugin or service, f.e. JSON. ? Regards, Andreas1 point
-
Thx adrian, that does indeed take care of it! Thx. Agree that this should be accounted for!1 point
-
@ryan - not sure if you'll see this, but I still don't understand why the "More Topics" sidebar is on the right on these pages: https://processwire.com/docs/more/multi-site-support/ https://processwire.com/docs/more/lazy-cron/ but on the left on this page: https://processwire.com/docs/more/coding-style-guide/ There is also an additional link at the bottom of the left sidebar to "More topics" which I don't really understand.1 point
-
Quietly and without interruption this week, our whole website (and all subdomains) moved from a single static server to a load-balanced multi-server environment, giving us even more horsepower and redundancy than before— https://processwire.com/blog/posts/processwire-hosting-upgrades/1 point
-
A terminal for running server commands: http://modules.processwire.com/modules/process-terminal/ https://github.com/adrianbj/ProcessTerminal NOTE: It does not support interactive commands like vi, nano, apt, etc. DO NOT attempt to use these as they may result in you needing to restart apache. This is a bash terminal that lets you quickly execute commands on a server. In addition to normal commands like: ls, cd, cat, mkdir, rm, chmod, chown, etc, you can also do mysql command line calls which is very handy if you need to add a new user, create a mysqldump etc. Note that for mysql commands you need to issue them individually - you can't simply start "mysql" and issue commands from there - each call needs to include your username and password and the command to be run, eg: mysql -u root -p mypassword -e "CREATE DATABASE newtablename"; There is also an upload and download command, eg "upload test.txt" which will spawn a file selector dialog on your machine to upload that file to your server with the given name. It also has arrow up and down for command history as well as tab autocompletion of commands and file names. This module was separated from Tracy because some shared hosts were flagging it as spam. This is because it uses system_exec to run server commands. This can certainly be dangerous, but in my opinion it is no more dangerous than the HannaCode module or the Tracy Console panel which both allow you to run system_exec. The key thing is that ProcessWire's htaccess rules prevent the shell.php file from being run directly and because this is a process module it uses PW's permissions to restrict usage to superusers.1 point
-
Yeap, I did realized that too. If one needs PW's out of the box pagination support, simply filtering with if($page->viewable()) is just not enough, it can only be used as a last resort to prevent information leakage but that does not necessarily mean issue-free code. The approach I came up with in a nutshell is (besides using PW's built in access control): Hooking after Page::viewable with custom access checks and using if($page->viewable()) where needed. Hooking before Page::render with custom access checks, in order to block certain page access cases. Added hook method (Pages::siteFind) which delegates its task to Pages::find but before doing so it modifies the selector string based on certain conditions in order to prevent fetching certain records in the first place. However, my approach is rather crude and hardcoded into the site, so there is a lot of room for improvement here. I do not know if I should spend the time on evaluating DynamicRoles as I do not have too much time to waste, but what makes it compelling is this bit I read in Ryans intro: "This module directly affects the results of all page getting/finding operations by applying the access control directly to the database queries before pages are loaded. As a result, it is fast (regardless of scale), pagination friendly, and requires no further intervention by the developer other than configuring the dynamic roles as they see fit." Anyway, if you guys no longer use DynamicRoles with current versions of PW, then may I ask what other approach you use? Any guidance would be appreciated.1 point
-
I'm also no longer using DynamicRoles in a production env. It was working well though with the fixes I proposed in the repo and on pw 2.7.3. An addition to @szabesz comments above: The thing to keep in mind with $page->viewable() as the "Solution for Access-Control" is that it's easy for it to not be enough. As soon as pagination is needed one needs access control at the database layer or pages will have different numbers of elements (even down to none at all).1 point
-
1 point
-
@thetuningspoon - if you go with Dynamic Roles, please grab this fork (https://github.com/matjazpotocnik/DynamicRoles/commits/master) by @matjazp because Ryan's version is pretty broken and seemingly abandoned.1 point
-
Here is a discussion related to this issue, in which Ryan explains the API decisions: https://processwire.com/talk/topic/11736-get-requests-not-subject-to-access-control To sum it up real quick (quotes): A $pages->find() or $pages->findOne() method that filters results is based on database-filtering, not runtime filtering. The API is based around providing methods for the developer to control access the way they see fit. The viewable() method is the basis of that. PW's access control model supports runtime hooks to Page::viewable. One shouldn't skip a $page->viewable() call regardless of what method you used to retrieve the page. When rendering frontend templates <?php if ($page->viewable()) : ?> (or $page->viewable('field_name'); ) is the way to go to check for default PW permissions. For example: https://processwire.com/talk/topic/4834-simple-hooks-tutorial-turn-a-pagearray-into-a-list-of-links/ ... // loop through each item in the PageArray and render some 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()) { $out .= "<a href='$page->url'>$value</a>"; // if page is viewable, make it a link } else { $out .= $value; // if page is not viewable, just display the value } } ... In order to "extend" the access control logic, one can hook after Page::viewable eg.: https://github.com/processwire/processwire-issues/issues/560#issuecomment-384656192 quote: // goes into /site/ready.php $wire->addHookAfter('Page::viewable', function($event) { $viewable = $event->return; if($viewable) return; // use PW's existing logic, since it said it was viewable $page = $event->object; if(!$page instanceof User) return; // this is an example for User templates only if(whatever logic you decide that $page is viewable) { $viewable = true; $event->return = $viewable; } });1 point
-
File Info A textformatter module for ProcessWire. The module can add information to local Pagefile links in two ways: As extra markup before, within or after the link As data attributes on the link (handy if you want to use a Javascript tooltip library, for instance) Screenshots Module config Example of output Installation Install the File Info module. Add the textformatter to one or more CKEditor fields. Configuration Add markup action (and general) Select "Add markup to links" Select the Pagefile attributes that will be retrieved. The attribute "filesizeStrCustom" is similar to the core "filesizeStr" attribute but allows for setting a custom number of decimal places. If you select the "modified" or "created" attributes then you can define a date format for the value. Enter a class string to add to the links if needed. Define the markup that will be added to the links. Surround Pagefile attribute names in {brackets}. Attributes must be selected in the "Pagefile attributes" section in order to be available in the added markup. If you want include a space character at the start or end of the markup then you'll need >= PW 3.0.128. Select where the markup should be added: prepended or appended within the link, before the link, or after the link. Add data attributes action Select "Add data attributes to links" Select the Pagefile attributes that will be retrieved. These attributes will be added to the file links as data attributes. Attributes with camelcase names will be converted to data attribute names that are all lowercase, i.e. filesizeStrCustom becomes data-filesizestrcustom. Hook If you want to customise or add to the attributes that are retrieved from the Pagefile you can hook TextformatterFileInfo::getFileAttributes(). For example: $wire->addHookAfter('TextformatterFileInfo::getFileAttributes', function(HookEvent $event) { $pagefile = $event->arguments(0); $page = $event->arguments(1); $field = $event->arguments(2); $attributes = $event->return; // Add a new attribute $attributes['sizeNote'] = $pagefile->filesize > 10000000 ? 'This file is pretty big' : 'This file is not so big'; $event->return = $attributes; }); https://github.com/Toutouwai/TextformatterFileInfo https://modules.processwire.com/modules/textformatter-file-info/1 point
-
1 point
-
Thanks @horst & @szabesz. I wouldn't want to install Admin on Steroids just for this, I actually use your module @horst https://modules.processwire.com/modules/page-tree-add-new-childs-reverse/ but personally I think this kind of thing should be in core. Why not multi-sort? Or at least a site-wide config flag to change default page tree sort from ascending to descending. This is a hurdle I hit every project, and I remember initially when using ProcessWire it was a roadblock until I discovered the modules to fix. It is more developers that are coming from other CMS that I am thinking of.1 point
-
Exactly. It's just a bit custom CSS. ? It might also be an idea for a matrix update that you can configure labels as images. Would be more flexible.1 point
-
I guess it's just CSS? a.InputfieldRepeaterAddLink.InputfieldRepeaterMatrixAddLink.InputfieldRepeaterAddLinkInit[data-type="3"] { font-size: 0; width: 150px; height: 100px; display: inline-block; background-image: url(https://via.placeholder.com/150); background-repeat: no-repeat; } span.ui-priority-secondary { display: none; }1 point
-
1 point
-
Curious, any plans to develop this further?1 point
-
Thanks, looks even better I often have a need for a WordPress "custom fields"-like field in PW and this module has this.1 point