Leaderboard
Popular Content
Showing content with the highest reputation on 01/18/2023 in all areas
-
PAGEGRID – A visual page builder for ProcessWire. Design fully responsive websites (or parts of them) without writing any code. Use ProcessWire's native templates (and fields) to create your own blocks. Rearrange and resize items in a visual way and use inline or modal editing to quickly edit the content of your website. Try PAGEGRID for free PAGEGRID is not free software. However, you can try PAGEGRID on your local machine or on a test server as long as you need to make sure it is the right tool for your next project. … and when you’re convinced, buy your license. Get it here Download from GitHub Download from Module Directory Requirements ProcessWire 3.0.210 or greater Installation Go to “Modules > Site > Add New“ in your admin Paste the Module Class Name "FieldtypePageGrid" into the field “Add Module From Directory“ Click “Get Module Info“ On the overview, click “Download And Install“ On the following screen, click “Install Now“ More install options Module install guide Site profile install guide Get up and running Quick start Create your own blocks or install the PageGridBlocks Module (installs premade templates and fields for PAGEGRID blocks). What's PAGEGRID? page-grid.com – Get to know PAGEGRID. Documentation – Read the official documentation. Issues – Report bugs and other problems. Forum – Whenever you get stuck, don't hesitate to reach out for questions and support. Why I build it ProcessWire is super flexible in itself and lets me build whatever I want. But building a custom website can be a lot of work. For some projects, I've ended up using a lot of templates and fields. To make my pages more flexible, I sometimes build my own little page builder based on the RepeaterMatrix or PageTable module. While these page builders were great for the specific site I was building them for, they were never flexible enough to be used for new projects, so I ended up customizing them frequently. The more complex they became, the harder it became to use them for my clients. After playing around with some WYSIWYG page builder tools, I realized that while they can save me a lot of time, they can also be very limiting or have expensive subscriptions and somehow tie you to their ecosystem. So I decided to build my own page builder based on the most flexible CMS I knew. Concept This fieldtype Renders block templates and adds drag and drop functionality in admin, as well as enable inline editing for text, and file fields. It also let's you manipulate CSS in a visual way to design fully responsive websites (or parts of them) without writing code. The fieldtype comes with an optional style panel to manipulate CSS properties directly on the page. You can customize the panel or disable it completely from the module settings (and just use a CSS file that you include in your template). The data to style the items is stored directly on the item using PW's meta data (no extra fields are created). Don't want to give your client all that power? Use ProcessWire’s powerful permission system to control what your clients can edit. You can then also grant access individually to the style panel, resize or drag functionality using ProcessWire's build in permission system. Features Blocks are just pages Blocks are defined by native PW templates and fields Manipulate CSS grid or flexbox based layouts in a visual way to design fully responsive websites (or parts of them) Encapsulated frontend code (PAGEGRID renders the template of your frontend inside an iframe in the backend) Design and editing features can be disabled for certain roles (using ProcessWire's build in permission system) Inline editing of text, textarea, TinyMCE (supports latest version), ckeditor and file fields Simply drag and resize to manipulate grid items directly inside the backend Manipulate grid columns and rows directly on the page (use any number of columns you want) All style manipulations are saved as JSON and used to generate dynamic styles that you render in your main template (no inline styles) Nested groups/grids (child pages of nested blocks are created under group parent) The style panel supports adding custom classes and assigning styles to them. These classes can be used globally on all pages (a css class is also a page) The style panel supports selecting html tags to style tags globally across the whole site Global blocks work with page reference field (changes on one page, changes all blocks on all pages) Manual and auto placement of grid items blocks and nested blocks can be cloned Redo/undo and copy/paste shortcuts Editing block items in modal sidebar immediately updates frontend (Ajax Save). Define custom icons for your blocks via native template settings (template -> advanced -> icon) Automatic page save (Changes are getting saved via ajax, no need to click the save button) NEW: Option to automatically load lazysizes lazyloader (V 0.1.0) Changelog V 0.1.0: Feature: Option to automatically load lazysizes lazyloader (Module Settings > Plugins). V 0.1.5: Fixed bug: Tabs not working when editing items via modal panel. V 0.1.6: Fixed bug: Setting height in VH unit was not working. V 0.1.7: Feature: Option to hide save button (and use automatic ajax save ) if there are no other fields than PAGEGRID on the content tab (Module Settings > Interface). V 0.2.0: Fixed bug: Custom block wrapper element <p> was not working with inline editor. V 0.2.0: Fixed bug: Inline editor would sometimes not save after clicking cancel and then edit item again. V 0.2.0: Feature: Now it's possible to add classes to elements inside richt text fields via style panel. V 0.2.0: Fixed bug: Inline editor was not working after first item was added to the page (needed reloading the page). V 0.2.1: Feature: Updated PageGridBlocks Module: Using TinyMCE as the default editor. V 0.2.1: Feature: Updated PageGridBlocks Module: Group/container wrapper element can now be changed to <div>, <section>, <article>, <header>, <footer>, <nav>. Thanks to everyone who helped me improve my coding skills and for the support of this great community! Special thanks to @diogo for the valuable feedback and @ryan for this great CMS and his support for the PageFrontEdit module!19 points
-
https://processwire.com/modules/lister-native-date-format/ is great for formatting lister dates, by the way. You can configure preferred default format for native date fields and switch format on the fly ?3 points
-
Your selector string will be "id=page.name_of_your_repeater_field, check_access=0". The "check_access=0" is so that it works for non-superusers. In the example below I'm using a repeater field named "test_repeater". If you repeater doesn't include the title field you'll want to choose something different in the "Label field" setting.2 points
-
Thank you all for all your answers. This is perfect, I even have the choice! Problem solved.1 point
-
@Robin S wow, same result as my template selection thing but this makes me understand how pw does it, thanks a lot ? @rooofl of course, Robin S example also works with a select made with a page reference field have a nice day1 point
-
Hi @rooofl I think you need to use the dot (.) sub field notation in your selector string. something like $page->font_style.type = somevalue The font_style is the repeater field and the 'type' is the field in the repeater field. Gideon1 point
-
It's not configurable, since the module config doesn't show system fields, but you can add them permanently with this little snipped for site/ready.php: <?php namespace ProcessWire; wire()->addHookBefore('ProcessUser::execute', function(HookEvent $event) { $process = $event->object; $process->showFields = array_merge($process->showFields, ["created", "modified"]); }); For changing the date format to something more precise, you can hook into the lister: <?php namespace ProcessWire; wire()->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { $page = wire('page'); // Only continue if we're actually listing users in the backend if($page->process !== 'ProcessUser') return; $lister = $event->object; // Assign whatever date format you like $lister->nativeDateFormat = 'Y-m-d H:i'; });1 point
-
hi again ? actually i'm referring to the field you use in the repeater, whether or not it's the one you use as the item title in the page as it is natively the one pw will use in a page reference field coming to this page reference it's just the type of field easy to populate with a list of "pages" of your choice, here the repeater elements, thanks to the fact pw create a template for the the repeater elements and a page for each element (bot the most poetic sentence... guilty as charged ? and, in this field parameters (input tab) you just have to choose your repeater template pw has created on the fly here, just for the example, my repeater was named... my_repeater ? have a nice day1 point
-
Thanks for the feedback. An unfortunate side effect of InputfieldPageListSelect is that it doesn't have an easy way to disable individual items in the tree for selection, and checking after the data is submitted feels a bit clunky. I'll try to find a hopefully intuitive way to add the check, but it may take a little while.1 point
-
I am doing the exact thing in a project and this is how I get those events: // all future events from "today" $events = $page->children("date_event>=today, sort=date_event, sort=time_from, limit=6"); The magic lies here. You can literally "tell" the selector what to do. You don't need any timestamps or date functions. date_event>=today You could also do things like: // get all events of the current year $events = $pages->find("template=event, date_event>='first day of this year', date_event<'last day of this year', sort=date_event, sort=time_from, limit=6");1 point
-
I've opened a request issue for my idea above: https://github.com/processwire/processwire-requests/issues/400 If you like that idea please show your interest by giving it a thumb up, thank you ?1 point
-
Up until now not one of the many softwares on github that I have been using even had branding attached. With pro modules the user knows exactly what to expect: buy and then use. With free modules that ask for money to remove brandings, the user could feel tricked. I'd rather prefer that for the same reason mentioned above. I happily pay for pro modules and use them a lot. I totally respect the way you see things in this matter and it is your freedom as a module developer to handle things like you do. Just wanted to share my thouights and feelings about it and explain some negative views people might have on your approach, especially since it is the first time I come across this in the PW module world. Enough said. Thank you for everything you're giving to the community and keep up the great work!1 point
-
I wouldn't consider forking an open source project and amending it to one's need as bad karma at all. This is what places like github, gitlab etc. is all about. I have to agree with @Robin S For me personally, it feels wrong having obligatory powered by links in a free module in the PW universe. You see that very rarely here. It is more common on other platforms, e.g. Joomla, and this was one of the many reasons that drove me away from there. Most of my clients do not accept links like that on their website. Contacting the developer to have this removed would cost extra time, both for me and the developer. So why not make it optional in the first place? I understand that this is a way to generate backlinks which generate traffic which generates attention and ideally more jobs which in the end generate money. But, again, it does not feel right to me to use a free PW module for that purpose. I totally appreciate the time that developers spend on releasing free modules and this is the spirit that makes projects like PW stand out. To generate income from a module one can always release a paid version. Free versions shouldn't have any strings attached.1 point
-
@pwFoo MarkupCache only supports strings and uses files for storage. WireCache supports arrays (of non-objects), PageArray and strings and uses DB for storage. WireCache is the way to go.1 point
-
API to change field settings: $field = $fields->get(164); $value = "newoption\n1=oldoption1\n2=oldoption2"; $module = $modules->get('FieldtypeOptions'); $result = $module->manager->setOptionsString($field, $value, true); var_dump($result); /** * description of function setOptionsString() found in Class SelectableOptionManager.php * Set an options string * * Should adhere to the format * * One option per line in the format: 123=title or 123=value|title * where 123 is the option ID, 'value' is an optional value, * and 'title' is a required title. * * For new options, specify just the option title * (or value|title) on its own line. Options should * be in the desired sort order. * * @param Field $field * @param string $value * @param bool $allowDelete Allow removed lines in the string to result in deleted options? * If false, no options will be affected but you can call the getRemovedOptionIDs() method * to retrieve them for confirmation. * @return array containing ('added' => cnt, 'updated' => cnt, 'deleted' => cnt, 'marked' => cnt) * note: 'marked' means marked for deletion * */1 point
-
Greetings, What makes ProcessWire so excellent is the ability to do all kinds of work at the API level, so that you can essentially create a custom admin for your projects. Editing a page is of course a crucial part of any custom admin. NOTES: Of course, you must cutomize this to your project. Also, in my code I am editing the page directly inside the page itself. In other words, you display a page as usual, but inside it you have your edit code, as well as code to save the page after editing. The other option would be to link to another page just for editing. Editing does get rather involved. Below is a technique I've used. I'll break editing down to several steps, then later I'll put it all together as one. Here goes... Step 1: Isolate Who Has Editing Rights You don't want anyone who can view the page editing it! I use code like this to limit editing to people with either an "editor" or "superuser" role. We open it here, and close it later in Step 6: <?php if ($user->isSuperuser() OR $user->hasRole("editor")) { Step 2: Set the $page Variables (Except Title) to Hold Edited Values Take inputs received from a submitted form and use those values to replace current $page values. For this example, I am only using two fields to keep it simple. And they are text fields. We hold off on setting the title, since that needs special handling: <?php if ($input->post->title) { $page->set("first_name", $sanitizer->text($input->post->first_name)); $page->set("last_name", $sanitizer->text($input->post->last_name)); } Step 3: Edit Title Field, but Only if the Title is Unique, Then Save the Page You need something like this so you don't get an error if the title you apply to the edited page collides with the title of an existing page. The code below confirms that the title is unique and allows you to set the title, and only then save the page: $thistitle = $page->title; $matchedtitle = $input->post->title; $checktitles = $pages->find("parent=/[path]/[to]/[parent]/, title=$matchedtitle|$thistitle"); $titlecount = count($checktitles); if($titlecount < 2) { $page->of(false); $page->set("title", $sanitizer->text($input->post->title)); $page->set("name", $sanitizer->text($input->post->title)); $page->save(); Step 4: Refresh URL Think about it... If while editing this page we changed the title, the URL you are on is no longer valid. Here's a simple bit of Javascript to handle this. The code below also closes out the conditional set in Step 3: $refresh=$page->url; ?> <script type="text/javascript"> window.location = '<?php echo $refresh ?>'; </script> <?php } Step 5: Handle the Scenario When the Page Title Collides In Step 3, we edited the page title because it passed the "unique" test. But what if it fails that test? We would move to this section of code, where a message lets the user know there is a problem. A bit of Javascript helps make the warning fade in so it is more noticeable: else { ?> <div class="admin_error_box"> <p>Sorry, there is already a page using this title: <?php echo $input->post->title?>!</p> <p>Please enter a different title in the form.</p> </div> <script> $(function() { $('.admin_error_box').hide().fadeIn(3000); }); </script> <?php } Step 6: The Edit Form We need a form to capture the submission of edits. It would look the same as your page-creation form, but would have to be pre-populated with the current values of the page, which will also change upon submission of the form. The last bit of code closes out the check on user roles set in Step 1: <div class="page_create_form_box"> <p class="form_heading">EDIT THIS PAGE USING THE FORM BELOW</p> <form action="<?php echo $page->url ?>" method="post"> <ul> <li><label class="label_class" for="title">Page Title:</label> <input type="text" class="input_class" name="title" value="<?php echo $page->title ?>"></li> <li><label class="label_class" for="first_name">First Name:</label> <input type="text" class="input_class" name="first_name" value="<?php echo $page->first_name ?>"></li> <li><label class="label_class" for="last_name">Last Name:</label> <input type="text" class="input_class" name="last_name" value="<?php echo $page->last_name ?>"></li> </ul> <button class="admin_submit" type="submit" name="submit">SAVE EDITED PAGE</button> </form> <?php } ?> Step 7: Putting it all Together Now let's put all of this code into one continuous routine. <?php if ($user->isSuperuser() OR $user->hasRole("editor")) { ?> <?php if ($input->post->title) { $page->set("first_name", $sanitizer->text($input->post->first_name)); $page->set("last_name", $sanitizer->text($input->post->last_name)); } $thistitle = $page->title; $matchedtitle = $input->post->title; $checktitles = $pages->find("parent=/[path]/[to]/[parent]/, title=$matchedtitle|$thistitle"); $titlecount = count($checktitles); if($titlecount < 2) { $page->of(false); $page->set("title", $sanitizer->text($input->post->title)); $page->set("name", $sanitizer->text($input->post->title)); $page->save(); $refresh=$page->url; ?> <script type="text/javascript"> window.location = '<?php echo $refresh ?>'; </script> <?php } else { ?> <div class="admin_error_box"> <p>Sorry, there is already a page using this title: <?php echo $input->post->title?>!</p> <p>Please enter a different title in the form.</p> </div> <script> $(function() { $('.admin_error_box').hide().fadeIn(3000); }); </script> <?php } ?> <div class="page_create_form_box"> <p class="form_heading">EDIT THIS PAGE USING THE FORM BELOW</p> <form action="<?php echo $page->url ?>" method="post"> <ul> <li><label class="label_class" for="title">Page Title:</label> <input type="text" class="input_class" name="title" value="<?php echo $page->title ?>"></li> <li><label class="label_class" for="first_name">First Name:</label> <input type="text" class="input_class" name="first_name" value="<?php echo $page->first_name ?>"></li> <li><label class="label_class" for="last_name">Last Name:</label> <input type="text" class="input_class" name="last_name" value="<?php echo $page->last_name ?>"></li> </ul> <button class="admin_submit" type="submit" name="submit">SAVE EDITED PAGE</button> </form> <?php } ?> My apologies for any problems with the formatting of the code above (please use your editor to assure proper tabs). Notes: - If you include checkboxes or other field types in your page, the editing is a bit more involved. - If you have image fields, you would have separate actions connected with those. For more information on handling image fields in custom forms, take a look at this: http://processwire.com/talk/topic/3105-create-pages-with-file-upload-field-via-api/ That should get you started! Follow up if you have more questions! Thanks, Matthew1 point