Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 09/06/2022 in all areas

  1. This week I've been working on something a little different: developing a new site profile in ProcessWire. Actually, I should probably call it an application profile rather than a site profile, as it's not a website profile. Instead it's a profile for an invoicing application in ProcessWire. Though you would install and run it on a web server, but it would be an independent application rather than part of a website... perhaps something you run in a subdirectory, subdomain, or even localhost. This is something I've been wanting to build for awhile—ever since the invoice service I use raised their rates beyond my budget. So I thought I'd build a replacement that I could use, as well as share for others that might have a similar need. I think it might also be a pretty decent PW profile example in general, too. I'd originally considered building it as a Process module but decided not to for a few reasons. Though the biggest one is that a site profile enables the greatest potential for customization and expansion according to each person's needs. Since you can expand upon it by adding your own fields and templates, or editing existing ones, most can really tailor it to their own needs a lot more easily than they could if it were a Process module. Likewise, since the actual invoices (and invoice emails) are rendered from front-end pages, you can customize the look and feel of them to match your brand very easily. (This is something I always wished I could do with the invoice service I've been using previously) This invoice profile requires nothing other than the ProcessWire core. It has no 3rd party or Pro module dependencies. I've got it largely functional at this stage, though will be putting a couple more weeks work into it before releasing it. I'd like to build in the option for clients to pay an invoice with a credit card (via Stripe) for instance. Below are a few screenshots of the work in progress. First is the page-list which shows the current invoices in the system and their status. (click image to view larger) As you can see, there are also pages for Clients and Settings. The client pages contain all the information about each client that invoices can be created for. The Settings page is where you can edit your own company information, logo and billing preferences. Next is the invoice editor. Here we have a repeater for each line item in the invoice. We also have a repeater for payments. All of the totals add up automatically as you type (Javascript added via hooks). They are also calculated automatically at the server side, so that everything stays consistent whether working with the API or in the page editor. (click image to view larger) At the bottom of the invoice editor you'll see a collapsed input for "Invoice action". This is where you can select actions to apply to the invoice. The two we currently have are "Email invoice to client" and "Email invoice to another address". Next up is what we see when viewing the invoice on the front-end. This is just the output of a template file but it is optimized for printing, saving to PDF and sending through email. I've kept it intentionally simple but of course the logo would be replaced with your own and all markup/styles are fully under your control. (click image to view larger) What I plan to add next are payment options, enabling a client to pay by credit card right from the invoice URL or email. What do you think, is this type of PW profile useful to you or someone you know? I've initially built it towards my own client invoicing needs, but I'm curious what other features you would like it to have? Or do you think it's better to keep it simple so that people can more easily take it in different directions? Thanks for your feedback. Have a great weekend!
    29 points
  2. This last week my wife and daughter took a trip to NYC and it was my daughter's first time there. I was browsing around online looking at things they could do and so I visited the Guggenheim museum website to look into that option... I've always been a fan of the building, a Frank Lloyd Wright masterpiece. In addition to New York, I learned from the website that Guggenheim also has museums in Abu Dhabi, Bilbao and Venice, so I clicked through to view them as well. I really liked the Venice Guggenheim website, which had a much nicer website than the other locations. It was such a nice site that I was curious what they were running, so I viewed the source and... not WordPress (like the others), but ProcessWire. What a nice surprise. Then I was curious about who made such a nice site and there was a credits link in the bottom right corner that says the site was made by basili.co, nice work! It's always fun to come across a ProcessWire powered website randomly like that, and I thought you all would enjoy this one too. This week there are fairly minor updates on the core dev branch. Though the updates include one I've been meaning to do for a long time: improve the API for processing Inputfield forms. Previously there's been no way to check if a form is submitted, short of checking an $input variable yourself. Today I committed an update that adds a $form->isSubmitted() method that solves that, and more. It can identify which form was submitted, which submit button was used, and it also performs additional checks to make sure it's a valid submission before deciding that it's a form worth processing. It improves reliability, accuracy and security. Next week I'll be updating several of the admin forms to use it, among other updates. A few other useful helper methods were added to the Inputfield forms API as well. I realize that these updates may only be of interest to module authors, but I like keep you up-to-date with the week's updates either way. Thanks for reading and have a great weekend!
    29 points
  3. This week we have ProcessWire 3.0.205 on the dev branch. Relative to 3.0.204, this includes 23 new commits including several refactored classes, issue resolutions, several pull requests and various new features. While there's no single major new feature to write a blog post around, there's still a lot here so for full details see the dev branch commit log. This week there's also a new module released in the ListerPro board called PageActionCrawl. This is a ListerPro PageAction module that crawls all pages sent to it. You can use this to crawl your entire site, some portion of pages within it, or even crawl external URLs referenced in URL fields. This is useful for any number of things such as priming caches, finding errors, quality assurance, doing security testing and more. Features include: Supports crawling with GET, POST or HEAD requests. Supports optional query strings and/or URL segments. Reports the HTTP response code and render time for each URL. Highlights error URLs (http code >= 400) in red. Optionally supports crawling of multiple URL variations per page. Supports inclusion of custom POST variables in POST requests. Supports page URLs or URLs stored in FieldtypeURL fields. Supports success and error hooks for custom behaviors on crawled URLs. Speaking of ListerPro actions, I've moved all of the 9 ListerPro action modules into their own new subforum of the ListerPro support board, so if you subscribe to ListerPro be sure to look for the new ListerPro Page Actions board in there. That's also where this new PageActionCrawl module is posted. Thanks for reading and have a great weekend!
    18 points
  4. This week my kids are out of school on fall break, meaning I've also been off work this week (in part at least), so it's been a quiet week for development. Nevertheless, an issue report has been resolved (thanks to matjazpotocnik), two feature requests have been added (here and here), and a bunch of minor core code improvements have been added. While there's not much more to report this week, more is on the way next week. Have a great weekend!
    15 points
  5. I am happy to announce that I will release an early beta version of my pagebuilder module PAGEGRID to selected users. The main focus of this testing is to make PAGEGRID production-ready. There is also an official website now. And a small, but growing documentation page. Both are works in progress, so expect some updates coming soon. You can find the initial post here (it's a little outdated). Iam sorry for those who missed it, but the subscription period for the beta ended. Please only post in this thread if you recieved a beta invitation. Dear beta testers, invitations have been sent out. Make sure to also check your spam folder for emails by gumroad. If you have any questions, want to report bugs or just give some feedback, feel free to post here.
    13 points
  6. I work every day with ProcessWire as 90% of our websites are built with it. We have a base install that we use for every new project, if anything from the weekly updates is an improvement on what we use in there, then we update our base install which will have the improvement on our next project. We also have a lot of retained clients who pay monthly to keep things running smoothly, again if there are any improvements in the weekly updates, we can slowly apply these to the retained projects going forward. The last major improvement in our workflow was the combo field which we use on all our latest projects, we wouldn't know about that if the weekly updates didn't exist. You mention being productive which I think is the best thing about ProcessWire. We have installs from years ago that are still running, and we don't have to worry about them, or care how they were built even if the client is not on a retainer, we just leave them. However, the client may come back and request some updates, we can start with running all the upgrades knowing that we have had very few issues in the past with just running upgrades, and we already know that behind the scenes there will be improvements in doing this, and improvements if we wish to use them with our coding. I guess what I am trying to say is you don't need to worry about the weekly updates if they don't have an impact on you, but the next time you check the documents you may see something that you can use as an improvement. I am sure nobody remembers all the improvements, I don't, nobody uses all of them, I don't, but they are there to use if you want and know about them. Everything still works with a site that you have already built if you just run an upgrade. There may be 51 weekly posts in a year I have no interest in, but 1 weekly post which is golden, I will take that for something I don't pay for (other than through the Pro modules). How does it make me learn coding, every day is a school day and seeing how things are done in ProcessWire makes me think in different ways when I am using other tools, I suppose that is what will happen when 90% of our websites are built with ProcessWire.
    10 points
  7. As it happens, I'm about to hop in a project where invoicing is a key part; while I don't know if I'll be able to use your site profile directly, at the very least it'll be interesting to dig in for ideas. What we see here already looks awesome 🙂 Would be nice if this was implemented in a way where one can easily swap the payment processor, kind of like what Antti did with PaymentModule (and PaymentStripe, PaymentPaypal, etc.)
    9 points
  8. Hello all, I have released RockFrontendTailwind, an extension module for RockFrontend. It extends Bernhard's module and adds an installation profile for site development with Tailwind CSS. Obviously RockFrontend is a required dependency for my module to work. This module aims to give you a quick start with a Tailwind based project. What RockFrontendTailwind does: A folder "rockfrontendtailwind" will be installed in site/templates. That folder contains all the configuration files needed to get you started with a webpack-based build pipeline for JS and CSS with webpack tailwindcss postcss with postcss-preset-env (for autoprefixing) babel (for transpiling) So rather than just building the CSS with Tailwind, the build pipeline also takes care of transpiling your Javascript based on configuration in a .browserslist file. Of course, the setup is opinionated. But people who are comfortable working with webpack can easily adjust / extend the configuration to their liking. The default configuration watches your JS and CSS files and compiles them into site/templates/assets main.css and main.js by default. All paths are configurable through a .env file. Live reloading during development is not part of the webpack configuration since this is handled by RockFrontend already in a very efficient way. Also a _main.php file including a very basic boilerplate for a typical setup will be placed insite/templates. It includes examples on how to render your JS and CSS assets. More detailed instructions over at github. Adding new profiles to RockFrontend through your own modules is quite straight forward thanks to the clear structure in @bernhard's module. RockFrontendTailwind can serve as a boilerplate. The only important thing is that the "profiles" folder structure remains the same. The module is currently in beta but runs very stable. It will eventually be released as an official module in the directory soon. If you want to give it a shot, I shall be happy to hear your feedback. If you are looking for a standalone webpack build pipeline with webpack-dev-server, you might want to have a look at https://github.com/gebeer/tailwind-css-webpack-processwire-starter Happy Coding!
    8 points
  9. Look at this example. Its made with the old version of RestAPI first made by @thomasaull years ago. To get the context, you can navigate to https://kingspark.fr and https://valideur.mykingspark.fr . I am speaking about a system which give the possibility to some of our client use their mobile or a barcode scanner device to give "free of charge parking" of their customer. Its composed with custom hardware, software and devices or mobile apps (you see it on GooglePlay). Image #1: List of Parkings // Image #2: The custom made SAGAS Terminal // Image 3: A configured User / Device available for registration and use. On the first picture, you can see a list of "Parkings", and some can have the "Valideur" functionality. We can configure attached devices and some users with specific role to get access for registration. And then, imagine the following. A customer land on the parking, grab a ticket and go to their rendezvous At the end, the guy in the office use his "Barcode Scanner" to "validate" the ticket of the customer; This mean that the customer will not pay anything when landing on the terminal to exit the parking, and when he will present the ticket on the barcode-reader installed on the terminal (the "black hole" you can see on the center in the picture), it will be recognized by another software and thought a call on ProcessWire Rest API backend. I made you two screencasts, the first is the software which once installed and registered, get the quota (number of validation available) from the user assigned to the license-code, and the second is my mobile which get notification sent from ProcessWire (by this module) from a monitoring system to get real-time information on registration. screencast.mp4 cap_pulseway.MP4 If you have any question, do not hesitate. There a more example, but you should get the whole idea 👍
    8 points
  10. Hi! We are Velvetyne Type Foundry, since 2010, we’ve designing and distributing free and open source typefaces. We are a non-profit organization. We are quite famous in the world of type design and open source design. We are currently working on a new website. We are focused on performances, and we want to show our fonts as SVG and not webfonts on our home page. Our website is currently using Processwire, and we want to stick to it because it’s amazing. I (author of this post) will take care of most of the development. We need a plugin that is able to generate an SVG path from a font file (present on the server), and a text. This script already does that pretty well and I think it can be a strong base for the font-to-SVG operation. We just want the admin page to be very user-friendly, taking care of the call to the font to SVG script and show its output. I wonder if anyone is able to do such a plugin an how much it can cost. Let me know if you can be interested.
    7 points
  11. Coming to an IntelliJ IDE (like PHPStorm) near you soon. Live Templates or snippets provide a short way to write repeating code. You enter an abbrevitation and the editor completes the code for you. Here is one example when I want to setup a new module: phpstorm64_aT7Nj2gxSv.mp4 @bernhard Has snippets for VSCode in his great RockMigrations module also, be sure to check them out, if you use VSCode. As I use RockMigrations in every PW installation I also add snippets for migrations: phpstorm64_fAD9MoUJLE.mp4
    7 points
  12. TLDR: Use custom selectors in page field selector: - check_access=role1|role2 ... - to control who can see results - field=[item.id] - to select on id of repeater item containing the page field. ------------ This module extends the capabilities of selectors specified in the 'input' tab of a page reference field, specifically when that field is part of a set of dependent selectors which may be inside a repeater item. The readme also attempts to bring together various existing documentation regarding the use of dependent page selectors and the enhancements that were provided by various PW versions. See https://github.com/MetaTunes/CustomDependSelects for full readme and to download. Please note that this is an initial alpha release. Please test in your own context thoroughly before using. Also note that PW3.0.200 is required and 3.0.203 is preferred.
    7 points
  13. I don't know if anyone pm'd you already but it can be quite simple if you only need to generate a static svg from a text input. I found this library https://github.com/kartsims/easysvg which would allow you to do it all server-wise if you have .svg font files at hand. My approach would be to have a file input for the font file, a text input for the text you want to generate the svg from, a textarea (closed by default and non-editable) to hold the svg code, and something like https://processwire.com/modules/inputfield-runtime-only/ to echo the textarea's content (the svg) as a preview. Basically a hook in `ready.php`: require "/path/to/easySVG.php"; wire()->addHookBefore("Pages::saveReady", function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); if($page->template->name !== "font") return; // or whatever if(!$page->fontfile && !$page->text) return; // file and text inputs // copy/pasting from easySVG example $svg = new EasySVG(); $svg->setFontSVG($page->fontfile->url); $svg->setFontSize(100); $svg->setFontColor('#000000'); $svg->setLineHeight(1.2); $svg->setLetterSpacing(.1); $svg->setUseKerning(true); $svg->addText($page->text); list($textWidth, $textHeight) = $svg->textDimensions($page->text); $svg->addAttribute("width", $textWidth."px"); $svg->addAttribute("height", $textHeight."px"); $page->svgcode = $svg->asXML(); // textarea input $event->arguments(0, $page); }); And in your `svgpreview` field/file (check RuntimeOnly doc) or template file: echo $page->getUnformatted("svgcode"); (I used getUnformatted in case there are textformatters but it would best if there's none in the field's settings) It's not tested and made on top of my head but I think this might work. (nice to see Velvetyne here btw, I like your work and a good friend of mine made La Savate 🙂)
    6 points
  14. New video is out 🥳 I hope it helps to get started with RockMigrations quickly! Feedback very welcome - it's really not easy to do videos about such complex topics, so if you think something is missing let me know! Happy to hear that @netcarver 🙂
    6 points
  15. Another example, clients receipts generated by the terminal are sent on real time to the "receipt app" which can be seen there: https://facture.kingspark.fr/ You can see something more than ~4M pages. This following example, is a dashboard for accouting things, a database of 10gb and more than 11M pages: (traduced by on-browser-google-trad)
    6 points
  16. Thx for sharing @zoeck It's always a little disturbing to read comments on such posts... So many wrong assumptions and judgements... It's such a shame... ProcessWire is such a brilliant and powerful tool. I've been working with PW extensively for several years now and still sometimes get the feeling that I'm just scratching the surface... And with all that power and complexity (beauty) behind the scenes ProcessWire still looks like something that even an intern can read and understand at first sight. How genius is that? And how wrong is this guy with his judgement?! But I can't blame him. I was in the same situation 8 years ago... I think that is a quite common reaction. And I wonder if we could do something about that. Or if we should? I don't know 🙂
    6 points
  17. I'd be very interested in some details and explanations on this 🙂 I've been working with forms quite a bit and sometimes things where a little unclear to be honest. For example sometimes I had to do a $this->trackChange('value') to make my inputfield module save anything. While I found a way to make it work it would be nice to better understand the inner workings of the whole process 🙂
    6 points
  18. @pwired sure, here you are. site/templates/fields/sections_next.php This file is responsible for outputting rendered HTML for the field called `sections_next`. It's called with the `$value` set to the value to be rendered, which in this case is a field of type PageTableNext. <?php namespace ProcessWire; /** * @global Page $page * @global PageArray $value * @global Field $field * @global Pages $pages * @global Config $config */ ?> <div style="margin:1rem;border:solid 1px yellow; background:#ffffe0;padding: 1rem;"> This is sections_next.php <?php if(!($value instanceof PageArray)) return; foreach($value as $contentElement) echo '<div style="border:solid 1px #fc0;background:#eefff8;padding:1rem;margin:1rem;"> The following is rendered by ' . $contentElement->template->name . '<br />' . $page->renderValue($contentElement, ($field->pathToTemplates ?? '') . $contentElement->template->name) . '</div>'; ?> </div> site/templates/fields/sections/hero.php This file and the one that follow are two example possible section/paragraph/block types. For my proof of concept, I created a "hero" one and a generic "section" one. This hero one crudely renders a big background image with some big text over the top. <?php namespace ProcessWire; $image = $value->background_image; $thumb = $image->size(1920, 700); ?> <div style="background-image:url(<?php echo $thumb->url ?>); padding: 4rem;margin: 0 0 2rem 0;min-height:60vh;"> <p style="color:#fc0; font-size:3rem; font-weight:bold; text-align: center; line-height: 1.4;"> <?php print $value->title; ?> </p> </div> site/templates/fields/sections/section.php The 'section' type has a body field and a select field letting the user choose Blue/Mauve/None for the background colour. <?php namespace ProcessWire; // here, $page is the main page tht was requested; $value is the Page object being rendered, the 'section'. ?> <?php $map = ['Blue' => '#0284ea', 'Mauve' => '#f0ddff', 'None' => 'transparent']; $selected = $value->background_colour->title; $bg = $map[$selected ?? 'None']; ?> <div style="border:solid 1px #cf0;background:<?php echo $bg; ?>; padding:1rem;margin:1rem;">This is section.php, rendering <code>$value</code> <h2>title: <?php print $value->title ?></h2> <p>colour: <?php print $value->background_colour->title ?></p> body: <?php print $value->body ?> </div> Other files Now the instructions for PageTableNext (ptn) tell you to copy some other files into your templates dir, but I've not figured out why! e.g. The instructions made me copy a file from the module to site/templates/PageTableNext/ptn.php, however I put exit() at the top of that file to test whether it was ever used and I've not found it to be doing anything, so I don't understand that! Here's my demo page content: In the editor it looks like this: ➊ shows the three blocks/sections/... that I've added (with the buttons at ➌). I clicked the arrow to 'open' the third section and you can see it at ➋ rendered using just the site/templates/fields/sections/section.php file. The UI is pretty nice; you can edit each section, move them around etc. Oh, one other thing, in the main page template (e.g. basic-page.php) you need to render the field that contains all the blocks/sections/etc. like so: <?php // If using 'delayed' output: $content = $page->render->sections_next; // If using 'direct' output echo $page->render->sections_next; One interesting thing is that if you use delayed output then your site/template/{page-type-name}.php needs to populate $content (or whatever vars you use in _main.php). However, the field templates all just use echo/print because they are rendered with output buffering capture. Hope this helps! It might help me too when I come to actually make a site with PW instead of just playing!
    6 points
  19. I still use 2012 code from time to time, it make me also smile when it happen. About the tutorials, a real website, it depend what you call a real website. (I am not being rude, and I get your point, but I think that the tutorials need be done by the community, maybe we should follow an official guidelines). For example, for me, you would need to put your hand in Vite, Svelte, and how to mix them with ProcessWire to get data which mean to build a module that will inject custom headers, or use an internal API, and make yo call ProcessWire Headless cms things. For others devs, it could be other stack / frameworks, and we all know there is a ton of them. So you end up in what PW is the best => freedom, and I think IMO that it will be hard to satisfy everyone. 👇 For beginners, there is some good up-to-date doc, like https://processwire.com/blog/posts/starting-with-the-blank-profile/ and also tutorials - https://processwire.com/docs/tutorials/ - and for a real damn good example real website, the update profile SkyScraper which can be visited there http://demo.processwire.com/ , downloaded, dissected and modified. Maybe, again, the real need is to organize better what's already exist.
    5 points
  20. Typography is not a simple topic but I'll try to explain how I use it. But first, the difference between EM/REM. Generally, an EM got it roots in print where it refers to the width of the upper-case M. When css came about, they changed it to refer to a relationship of the parent element. By default, one EM generally is 16 pixels in the browser world. The REM (Root EM) is in relation to the root (usually the HTML definition if no ::root{} is defined) font size as you have defined in CSS. Some inconsistency -- You can use both EM and REM in margin/padding definitions. However, when using EM as the unit in a margin definition it looks only at the current element; It does not refer back up to a parent. This is not the case with REMs. The REM declaration is always looking at the root. // EM html { font-size: 16px; } article { font-size: 20px; } p { font-size: 1.1em; margin-bottom: 1em; } <article> This is 20px. <p>This is 1.1 x 20px. The bottom margin is 1.1em regardless of parent font size setting.</p> </article> // REM html { font-size: 18px; } article { font-size: 20px; } p { font-size: 1.1rem; margin-bottom: 1rem; } <article> This is 20px. <p>This is 1.1 x 18px. The bottom margin is 1 x 18px.</p> </article> The viewport width/height (VW/VH) allows for a 'fluid' scaling. However, the drawback is that smaller devices will not zoom in or out should the font size scale too small. Also, on very wide screens this scaling would likely make the text way too big, to the point of interfering with other content. My method: I define my base font size as 16px (usually the browser default). I also include variables to make future changes very simple. I put my font size break points at the top of my css file (usually after ::ROOT{} ) so that I don't have to go hunting should I need to change something. To avoid the confusion between parent references, I define all font sizes, margins, paddings, widths, etc. in REMs, except for the base ::root{} definition which is in pixels. :root { --fs-norm: 1rem; // defaults to browser's font-size definition --fs-big: 2rem; --fs-hdg: clamp(3.5rem, 10vw + 1rem, 14rem); // This sets the min and max font-sizes and scales in between } @media (min-width: 40rem) { :root { --fs-norm: 1.125rem; --fs-big: 3rem; } } body { font-size: var(--fs-norm); line-height: 1.6; } h1 { font-size: var(--fs-hdg); text-transform: uppercase; } I hope this helps. Like I said, this isn't a simple topic where you can say, "Use x because...". ps. Not a front-end guru so others may have a better reply.
    5 points
  21. This might be a somewhat niche module but I had a need for it and maybe others will also find it a useful development helper. Lister To Clipboard Easily copy a selector for the current Lister filters or selected results to the clipboard. For superusers only. Why? Lister or Lister Pro is handy for finding pages according to certain page attributes or field values and you can see the matched pages in a results list. Sometimes I want to run code on some or all the Lister results. Lister Pro allows results to be processed through Page Action modules but there are a couple of downsides to this: To execute custom code you would have to create a custom Page Action module and this may not be worth the trouble for a one-off operation. If you want to process only selected individual pages you can only select items from one page of the results. If you navigate to a different page within the paginated results the selection is lost. Lister To Clipboard gives you an easy way to copy a selector for the current Lister filters or a selection within the results so you can paste it into the Tracy Debugger Console or use it elsewhere in your code. Usage In Lister (Find) or in a Lister Pro instance, create filters to match the pages you want to target. If you want to select individual pages within the results, click an empty area of the cell within the first column (i.e. don't click directly on the page title). The cell will get a green background to indicate that it is selected. If there is more than one page of results you can move around the pagination to select more pages. Below the Lister results there is a blue box showing a selector string that will find the pages shown in your Lister results (or your selection within those results) when used in $pages->find(). Click the copy icon to copy the selector to the clipboard, then you can paste it into the Tracy Debugger Console or wherever you want to use it. https://github.com/Toutouwai/ListerToClipboard https://processwire.com/modules/lister-to-clipboard/
    5 points
  22. We really like the ability to add redirects via the page editor, but it is annoying that this functionality is only available to superusers. We often have clients asking us to add a 'short url' redirect for a page (e.g. /jobs -> /about/work/jobs) when it really is something they should be able to do themselves. To solve this problem, we've created ProcessPageRedirects. It does two things: Creates a page (Pages > Redirects) which lists all the visible pages to that user and the number of redirects (among other things) Allows them to manage the redirects for pages they can edit The redirects editor is the same one the superuser gets when editing the page. I hope this is useful, let me know here if you come across any issues with it.
    5 points
  23. If you are a designer not a developer, then I would suggest trying to move a site from one CMS to another is a bit of an ask. If you are happy with the structure and just want to modify content, then you should be able to do that in ProcessWire without any particular technical or coding skills. If you want a new look and feel and don’t want to use a developer, then maybe start from scratch in WP, just copy and paste what content you need. That assumes that you are proficient in WP. I gave up on WP because, while it looks simple, the complexity goes up exponentially the more you try to do.
    5 points
  24. It is no secret that Wordpress attracs a lot of no-coders and low-coders because of it's available template market. The no-coder buys a template on envato, themeforest, templatemonster, etc. and sells it as a website to the client. Most of the clients don't even know they bought an envato template website because they have no time and no website experience. By the time the client needs to have something changed, the wordpress template limitations won't allow for it and the no-coder is long gone selling a template somewhere else. Sooner a later the client is forced to call for a real coder for the needed level of support. Pagebuilders will attract even more no-coders and low coders. Having followed the Pagebuilder scene in Wordpress with Beaver, Bakery, Brizy, VisualComposer, Elementor, Genesis, Gutenberg, Themify, Divi, Oxygen, GeneratePress .... the list goes on and on. There is almost every month a new Wordpress Pagebuilder on the block. Why spend time in learning the Pagebuilder of the day if you could spend that same time in learning html, js, css and php and never need a Pagebuilder in the first place and give the Client a website that he really deserves: without Template limitations, unused theme functions and without all the Pagebuilder bloated code. Coming to my point: I hope that what is happening in the Wordpress Pagebuilder scene will never happen with future Processwire Pagebuilders.
    5 points
  25. Hi @jsilmarovi You could bootstrap PW instance to your Laravel app https://processwire.com/docs/front-end/include/ and that use PW api to create or edit pages https://processwire-recipes.com/recipes/create-page-via-api/ https://gist.github.com/lokomotivan/e0a20f96b6df02970bccd700a119930e
    5 points
  26. @benbyf In your PW admin, when in debug mode, there is a "Debug" link at the bottom right of the screen. If you click that it opens a panel and one of the options in the panel is "Hooks". Click Hooks to open and it'll show you all the hooks that are in use and in what order. The "priority" column indicates order... The smaller the priority number, the earlier it executes, so a priority of 99 executes before 100. But in the Hooks list on the debug screen you'll see priority numbers like 100.0, 100.1, 100.2, etc. This indicates that the hooks were added with the same priority (100, which is the default) and the number after the decimal indicates the order they were added in. They execute in the same order, so 100.0 executes before 100.1, 100.1 executes before 100.2, etc. If you are looking for a way to get this info for some other purpose you can find the code that generates this debug info in /wire/templates-admin/debug.inc, but basically it amounts to a displaying the return values from wire()->getHooks('*');
    5 points
  27. Another German Processwire „Review“ “When web development has to be quick“: https://www.golem.de/news/processwire-wenn-webentwicklung-schnell-gehen-muss-2209-167784.html
    5 points
  28. Usually I set the font size in the html or body tags, and then use rem for pretty much everything else. I use em in the rare occasions that the size of an element should definitely dependent on the size of the parent, but usually I want the flexibility to control them independently of each other with rem. When you use em on everything, it's very easy to overlook small differences between the text inside elements and you end up having the same kind of text set in 11.5px and 12px in different places, for instance. As for the base size itself, it depends a lot on the layout. Some layouts account for large screens, and divide into multiple columns. On those cases the base font can usually stay the same though any screen size, and can be set in pixels or em. On more static layouts I normally want the font to grow a bit with the screen width, but not too much (I mean, not proportionally. I want it to grow less and less as the screen becomes larger). For that I use a calc() to create a relation between the vw and the pixels. For instance: font-size: calc(8px + .7vw); And I usually want to define a minimum and a maximum sizes. This can be done with media queries, or simply by using the clamp function: font-size: clamp(15px, calc(8px + .7vw), 20px); This defines that the font grows with the screen width but never becomes smaller than 15px or larger than 20px.
    4 points
  29. I've been successfully using Dark Reader for years, with these settings (Filter+ is need for my Mac so that coping text still results in the original colors, not the changed ones of the view):
    4 points
  30. This is great. A few years ago I worked briefly for a security company and one of my responsibilities standing in for the accountant when she was off, was billing for services (mainly door security - 'bouncers' here in the UK) and we used an online system very much like this. Some summary pages (monthly/yearly/all time totals etc) would be an obvious addition and tax liability calculations where appropriate perhaps. Of course, being built on top of PW, customisation should be straightforward on this kind of foundation.
    4 points
  31. Just sharing an admin dark mode theme. Still a WIP, I need to figure out how uikit-inverse colors work and a switcher will be pushed. (great rock job @bernhard) Feel free to try it, submit issue or better pull-request. https://github.com/flydev-fr/ProcessWireAdminDarkMode
    4 points
  32. A note for myself, and people interested on how an install can scale : ProcessWire 3.0.175 adds new database scalability options https://processwire.com/blog/posts/pw-3.0.175/
    4 points
  33. In general: Apache servers are case sensitive. A request for /directory/file will be treated as a request for a different file than one for /Directory/File. Search engine’s are case sensitive. They’re going to view /directory/file and /Directory/File as the locations of two different documents In processwire: https://processwire.com/talk/topic/23223-allow-upper-case-in-url/ https://processwire.com/blog/posts/page-name-charset-utf8/
    4 points
  34. I'll share my youtube videos in this thread and if you have questions this is the place to ask. You can also subscribe to this thread to get notified when I post new videos 🙂 Here is the link to my channel: baumrock.com/youtube --- Hey! I've just published my very first ProcessWire video. It's about RockFrontend: https://processwire.com/talk/topic/27417-rockfrontend-🚀🚀-take-your-processwire-frontend-development-to-the-next-level/#comment-225666 Here is the video: What do you think? Do you understand what I'm trying to explain (despite the many ääähms und öööhms...)? 😄 What about the length?? I really didn't plan do get to 40mins... Did anybody even watch it till the end? 😅 Would it be easier to follow when having a small thumbnail in the bottom corner when working on the code? Or better without? Is it worth the effort of creating a video or would a readme be just as good? 😛 Any tips for better sound/lighting? I'm not really knowing what I do, so any ideas for improvements are very welcome 🙂 Better with or without background music? So many questions... So much to learn... 😄 But it's fun and I'm a bit proud 😎
    4 points
  35. That's of course true, but it would still be interesting to hear. For example if the reason is that the ProcessWire page is slow and a WordPress site would be faster, than that would be a wrong assumption and making the ProcessWire site faster would be maybe two hours of work while migrating the site to WordPress would easily be multitude of that... 23.4MB for the homepage is really not a good value and just by optimising your slider images (which should be as easy as using $img->maxSize(...)->url instead of just outputting the image in its original resolution via $img->url what your site is doing) you are able to speed up the site significantly. Then purchase and install ProCache and your site is insanely fast. That might be all you need. Because I think the design is nice and it also looks nice on mobile. So why throw that in the bin? If there are other reasons then these optimisations might be irrelevant of course. So it would be nice to hear your reasons 🙂
    4 points
  36. If by "featured" you mean "linked to within a CKEditor field" then it's pretty easy. You just upload the file to the first page it will be used on (Page A), and on any of the other pages you use the CKE link dialog to select Page A and then select the file.
    4 points
  37. Ryan has already stated lots of times that he is not interested in growing the user group just for the sake of growing it. In other words, it is very low priority for him, as far as I understand it. He is also not interested in page builders as such, but happy to add features to Repeater Matrix that support such use cases whenever he has the time to work on it. I guess that will be the closest to "page building" from Ryan. "Theming" will certainly never be possible with ProcessWire as a core feature as that would be agains its philosophy, wouldn't it? A solo or a team of developers can surely come up with their own theming schema and implement it for themselves but that is a different story, I think.
    4 points
  38. In the past I had used the old version of RockMigrations for some simple tasks like adding fields and templates which turned out to be huge time saver. But only just recently I started to use the new version and to discover the possibilities of this tool in more depths. And what should I say, I am really amazed. Once I had grasped the core concepts and, with @bernhard's help, had learned how to use it in a more structured way and in different contexts, it turned out to to be an even bigger time saver. I hate repetitive tasks. Adding fields and templates and fields to templates and configuring labels / access rights etc for fields in the template context in PW is a pleasure when using the GUI. But it is still a repetitive task. With RockMigrations I can have definitions of these fields / templates and fields in template context in a single file and reuse that. In a matter of seconds I have my reusable base structure available to start off a new project. Adding new structure through the GUI in a staging environment and then having to replicate it on the live sytem through the GUI. Repetitive task again. Pushing a migration file to the live system and running the migration. Again in a matter of seconds. Writing migrations wherever I want is also a great feature. Be it inside site/migrate.php or inside a newly developed module, it doesn't matter. RockMigrations will find it and do its job. At the beginning I wasn't sure how to define different field types with all their different properties. RockMigrations comes with VSCode snippets that make things easy. Or you can create a field in the GUI and then just copy/paste the code for the migration from the GUI to your migration logic. So however you prefer to create your fields, RockMigrations has you covered. This post may sound like an advertisement. But I just wanted to express how happy I am after having made the decision to spend some time to learn how to work with this module. That time was definitely well spent. Big thanks to Bernhard for creating this and releasing it as a free module.
    4 points
  39. But role is a thing, and permissions is another and this last is what you are looking for. Look there - https://processwire.com/docs/user-access/permissions/ - and try to play with them, then give a look at those modules : https://processwire.com/modules/admin-restrict-page-tree/ https://processwire.com/modules/custom-admin-menus/ For example, I have a role "accountant" and he do not have access to the page tree or any other features than the "accounting" module.
    4 points
  40. RockFrontend got some really cool updates over the last days thx to some inputs from @gebeer! The latest additions improve SVG rendering and finally I found a way to get rid of the need to add |noescape to every alfred() call in latte files 🥳😎 SVGs You can use the render() method to write SVG markup directly to your template file: // latte // icon is in /site/templates/img/icon.svg {$rockfrontend->render('img/icon.svg')} // php echo $rockfrontend->render('img/icon.svg'); You can even provide variables to replace, so you can create completely dynamic SVGs with custom rotation angles or colors etc... {$rockfrontend->render('img/triangle.svg', [ // replace the {rotate} tag in the svg markup 'rotate'=>45, 'color'=>'blue', ])} // add the replacement tag to your svg file // img/triangle.svg <svg style="transform: rotate({rotate}deg); border: 2px solid {color};">... PS: You can also use $rockfrontend->svg('img/triangle.svg') if you want 🙂
    4 points
  41. This week on the core dev branch we’ve got some major refactoring in the Page class. Unless I broke anything in the process, it should be more efficient and use less memory than before. But a few of useful new methods for getting page fields were added in the process. (A couple of these were also to answer feature request #453). Dot syntax You may have heard of dot-syntax for getting page fields, such as $pages->get('parent.title') where “parent” can be any field and “title” can be any field that has subfields. This is something that ProcessWire has supported for a long time, but it doesn’t get used much because it was disabled when output formatting was on. So it wasn’t something you could really count on always being there. Now you can — it is enabled all of the time. But it’s also been rewritten to be more powerful. When using dot syntax with a multi-value field (i.e. any kind of WireArray value) you can also specify field_name.first to get just the first value or field_name.last to get just the last value. i.e. $page->get('categories.first'); will take a value that was going to be a PageArray (‘categories’) and return just the first Page from it. Bracket syntax With bracket syntax you can call $page->get('field_name[]') with the (‘[]’ brackets at the end) and it will always return the appropriate array value for the type, whether a PageArray, WireArray, Pagefiles/Pageimages, or regular PHP array, etc. This is useful in cases where you know you’ll want a value you can foreach/iterate. Maybe you’ve got a Page field that set set to contain just 1 page, or maybe you’ve got a File/Image field set to contain just 1 file. But you want some way to treat all of your page or file/image fields the same, just append “[]” to the field name in your $page->get() call and you’ll always get an array-type value, regardless of the field settings. This bracket syntax can also be used for getting 1 value by index number. Let’s say you’ve got a page field named “categories” that contains multiple pages. If you want to get just the first, you can just call $page->get('categories[0]'); If you want to get the second, you can do $page->get('categories[1]'); This works whether the field is set to contain just one value or many values. Using the first index [0] is a good way to ensure you get 1 item when you may not know whether the field is a single-value or multi-value field. Another thing you can do with the bracket syntax is put a selector in it to filter a multi-value field right in the $page->get() call. Let’s say you want all categories that have the word “design” in the name. You can call $page->get('categories[title%=design]'); If you want just the first, then $page->get('categories[title%=design][0]'); What’s useful about using selectors in brackets is that this does a filter at the database-level rather than loading the entire ‘categories’ field in memory and then filtering it. Meaning it's a lot more memory efficient than doing a $page->get('categories')->find('title%=design'); In this way, it’s similar to the already-supported option to use a field name as a method call, for instance ProcessWire supports $page->field_name('selector'); to achieve a similar result. Dot syntax and bracket syntax together You can use all of these features together. Here’s a few examples from the updated $page->get() phpdocs: // get value guaranteed to be iterable (array, WireArray, or derived) $images = $page->get('image[]'); // Pageimages $categories = $page->get('category[]'); // PageArray // get item by position/index, returns 1 item whether field is single or multi value $file = $page->get('files[0]'); // get first file (or null if files is empty) $file = $page->get('files.first'); // same as above $file = $page->get('files.last'); // get last file $file = $page->get('files[1]'); // get 2nd file (or null if there isn't one) // get titles from Page reference field categories in an array $titles = $page->get('categories.title'); // array of titles $title = $page->get('categories[0].title'); // string of just first title // you can also use a selector in [brackets] for a filtered value // example: get categories with titles matching text 'design' $categories = $page->get('categories[title%=design]'); // PageArray $category = $page->get('categories[title%=design][0]'); // Page or null $titles = $page->get('categories[title%=design].title'); // array of strings $title = $page->get('categories[title%=design].title[0]'); // string or null // remember curly brackets? You can use dot syntax in there too… echo $page->get('Page “{title}” has {categories.count} total categories'); I’m not going to bump the version number this week because a lot of code was updated or added and I’d like to test it for another week before bumping the version number (since it triggers the upgrades module to notify people). But if you decide to upgrade now, please let me know how it works for you or if you run into any issues. Thanks for reading, have a great weekend!
    4 points
  42. I am used to use rem, the reason => web accessibility => a pixel is not responsive and with some algebra (lol) for fluid typo, the concept is called Poly Fluid Sizing and using tailwindcss utilities👇 Rule them all with this linear equation definition, which result the font-size : Take a look at this sample: https://codepen.io/neil/pen/agzZVg And give a read to : https://www.smashingmagazine.com/2017/05/fluid-responsive-typography-css-poly-fluid-sizing/ ✌️ Edit: for the rest, everything with a tailwind.config.js, it's so cool: https://tailwindcss.com/docs/grid-template-columns & #arbitrary-values
    3 points
  43. MagicPages (eg HomePage.php) do now also load the related CSS and JS files (eg HomePage.js and HomePage.css) in the backend page editor 😎 And there is a new WIKI page about MagicPages: https://github.com/baumrock/RockMigrations/wiki/MagicPages Magic Assets If your page is a MagicPage it will load YourPage.css and YourPage.js files automatically in the PW backend when editing any page of type YourPage. Example: // /site/classes/HomePage.php // /site/classes/HomePage.css div { outline: 2px solid red; } // /site/classes/HomePage.js alert('You are editing the HomePage');
    3 points
  44. For a long time I dived directly in templates and code to build a website. I changed that old workflow and use prototyping and wireframing a website first in Lunacy and Pencil. Only after that I port it to processwire code.
    3 points
  45. One more possibility: get your non-user pages by path instead of by ID. If you use PagesLoader::getByPath() it should be just as robust as getting by ID because page path history will handle any renaming or moving of pages. And as a bonus the code is more readable because it's more obvious what page is retrieved by '/about-us/sustainability/' than by 24875. $p = $pages->loader()->getByPath('/about-us/sustainability/', ['useHistory' => true]));
    3 points
  46. https://processwire.com/modules/app-api/ ?
    3 points
  47. A few new additions to this old module, available as of version 1.8.0 (session.txt import) and 1.9.0 (new API methods): There's an option in ProcessLoginHistoryHooks module config to import login history from session.txt. This can be useful when adding this module to a site with existing history, since ProcessWire (by default) collects data about successful/unsuccessful login attempts to said log file. This option is intentionally hidden under collapsed "advanced" fieldset. It's not super well tested yet, could result in a very slow request in case there's a lot of data to import, and in case disk timezone is different than the one in database duplicate records may be created on first run. $this->modules->get('ProcessLoginHistoryHooks')->getUserLoginHistory($user, $start, $limit, $login_was_successful) returns login history data for provided ProcessWire User object. Default values are 0 for "start", 2 for "limit", and 1 for "login_was_successful", which means that by default this method will return latest successful login and the one before that. Return value is always an array; in case there are no results, an empty array is returned. $user->getLoginHistory($start, $limit, $login_was_successful) does the same as previous command for a specific User object. All arguments are optional. This method returns a single timestamp (when limit is 1, or an integer value is provided for the "start" argument and "limit" argument is omitted), an array of login history, or null in case there are no results. By default timestamps for last two successful logins are returned.
    3 points
  48. Hello @Martinus, maybe findRaw() could simplify your solution: $a = $pages->findRaw("parent=/products/, seller=amazon, rating>0", "rating"); print_r ($a); // check array echo array_sum($a); // sum of all values in array Regards, Andreas
    3 points
×
×
  • Create New...