Leaderboard
Popular Content
Showing content with the highest reputation on 04/29/2024 in all areas
-
Version 1.3.7 is out This version comes up with some new additions as discussed in this forum in the last time. To check out what is new, please read the changelog.md As always, please keep in mind, that this is a new version with a lot of changes. I have tested almost all scenarious, but there could always be an unwanted behaviour. So keep an eye, that everthing works as expected. Otherwise please write an issue report (here or directly on GitHub). Have a nice week!2 points
-
I like this update you've done, which held my attention longer than expected, especially with the engaging texts in the Services section. Your dedication to improving the user experience is evident in the details, along with the variety of content blocks and auxiliary elements. I imagine you put a lot of effort into creating many pages and fields to set it all up. Well done @Leftfield and all the best! P.S. believe it or not, I actually read your Privacy Policy ?2 points
-
It's long overdue for a refresh of a personal website. At least it was built on the fantastic ProcessWire! Pats website awkwardly. I gave this poor thing a makeover before it got mistaken for a museum exhibit. I hope for positive comments, but I would rather listen to what the critics say to improve. It is not yet tweaked to the details (I am on the heroin run for the proper images for service pages), but it is something I can brag about. Here is the link: Digital Marketing Montenegro1 point
-
1 point
-
@maximus actually there is already ratio inside the pageimage class see here: https://processwire.com/api/ref/pageimage/ And you could also solve this without generating new images. You could set a square container and put the orginal img inside it. Then use CSS to get what you want.1 point
-
I think he means the "ProcessWire Weekly #519" Newsletter ? This does not come from Ryan but from @teppo1 point
-
Thank You! Ah, the Privacy Policy! It is a fascinating bedtime story, the legalese equivalent of watching paint dry. But not Terms and Conditions @OLSAbecause you would ping me for a beer next to the sea.1 point
-
@ryan - I need it for coupon codes which are stored underneath categorizing branch parents, but which are accessed by end users via a urlsegment on the home template. I have been using a hook to ensure duplicates can't be accidentally created and that works fine so not critical that this is added for my needs but just wanted to see if you thought it was still something that should be added to the core.1 point
-
You need to expand the parent select and navigate to the assigned parent. When you hover on that, you should see the "unselect" button.1 point
-
Hi @Christophe Unfortunately we don't have Code Intellisense or autocomplete in latte files at the moment ? See https://github.com/smuuf/vscode-latte-lang/issues/5 You are adding the method "listchildren()" to your ParentPagePage, nowhere else. That means you can all this method only on pages that have the template "parent-page". Why should it do that? You are calling a method of an object. If that does not exist it is expected to throw an error. You CAN do what you describe though. Sometimes it is useful and I'm doing that as well. You could add that method to your DefaultPage.php and there return an empty sting. That would make $page->listchildren() return "" by default, which means it does not throw an error. For some page types you can then implement a different logic: DefaultPage.php --> listchildren() { return ""; } FooPage.php extends DefaultPage --> listchildren() { return "foo!"; } BarPage.php extends DefaultPage --> listchildren() { return "BAR"; } // in any template echo $page->listchildren(); That it totally up to you. Same with regular ProcessWire templates. It's up to us devs how we organise things and everybody does it differently. I can only say what I came up with and what works great for all kings of projects (from very simple to very complex ones): layout.latte for main markup /site/templates/sections/... for all sections /site/templates/partials/... for all partials Details: layout.latte --> holds the html markup skeleton of the page, eg: <html> <head>...</head> <body> <header>...</header> <main>...</main> <footer>...</footer> </body> </html> Then all my template files are usually empty (like home.php, basic-page.php, foo.php, bar.php). Next, I divide my design into sections. A section is a portion of the page that goes from the very left to the very right and has an undefined height/content. You can then add those sections to your main markup file like this: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {include "sections/content.latte"} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> This is often all I need, because I build all the available sections in RockPageBuilder and then I can simply add them to the pages as I need them. But it works without RockPageBuilder as well. You then just need to code all your page layouts depending on the page template. If all those pages share the same breadcrumbs and content-footer it could look like this: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {if $page->template == 'foo'} {include "sections/content-foo.latte"} {elseif $page->template == 'bar'} {include "sections/content-bar.latte"} {else} {include "sections/content.latte"} {/if} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> You could also use a dynamic approach: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {include "content/" . $page->template . ".latte"} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> It's just regular PHP inside the latte tags, so you could also do is_file() checks etc: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {var $file = "content/" . $page->template . ".latte"} {if is_file($file)}{include $file}{/if} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> Obviously you'd need to create those files. Here I'm placing them into a new folder called "content", which would be /site/templates/content/foo.latte for example. Next, partials: If you have repeating markup inside your sections you can outsource them into the partials folder. For example let's say you want to show a blog overview page that shows all single blog items as cards. You'd have a section like "blog-overview.latte" like this: // blog-overview.latte <div uk-grid> <div n:foreach="$page->children() as $item"> <div class="uk-card"> <h3>{$item->title}</h3> <p>{$item->teaser()}</p> </div> </div> </div> This example is very simple and if you only use your cards here, then it's easier to leave them here. If you are using the exact same cards on two or three places then you can create partials for them: // blog-overview.latte <div uk-grid> {foreach $page->children() as $item} {include "partials/card.latte", item: $item} {/foreach} </div> // /site/templates/partials/card.latte <div> <div class="uk-card"> <h3>{$item->title}</h3> <p>{$item->teaser()}</p> </div> </div>1 point
-
It's been talked about elsewhere here in the forums, but an alternate idea would be utilizing .env files. It would satisfy both the installation process and long-term management of values. Some benefits: Widely used across applications, frameworks, and languages running in a web server environment and strongly recommended as a standard practice Secure by default. Web servers do not serve .env files Provides the ability to manage local and production configurations separately Frameworks like Laravel provide a .env file as well as a .env.example file containing all variables used in the application. This is kept up to date, used to document application requirements, and is committed into the repository Values that are not security-critical can be safely stored in the example file Provides a convenient location for additional non-ProcessWire site/app specific values such as API keys, or those required for modules Solves the issue of excluding site/config.php from a repository given that it's a required file containing specific syntax and $config object property assignments If .env was available in ProcessWire I would have my Fluency module look for translation API keys there rather than store them in the database. A benefit there is that different environments like local/ staging/production can mean an environment that is yours and an environment that is a client's. Pulling the latest copy of a database from production wouldn't require manually re-configuring modules that require API keys, or module registration keys. It would be good to eliminate storing security-critical values in PHP files entirely. The .env file could be generated and populated during the ProcessWire install process pre-excluded in the .gitignore file. Example: ENVIRONMENT="development" # ProcessWire PW_DB_HOST=localhost PW_DB_NAME="your_database PW_DB_USER=your_database_user PW_DB_PASS="LowuHeju7[BoI3" PW_DB_PORT=3306 PW_DB_ENGINE=InnoDB PW_DEBUG=true PW_CHMOD_DIR=0755 PW_CHMOD_FILE=0644 PW_USE_PAGE_CLASSES=true PW_USE_FUNCTIONS_API=true PW_PREPEND_TEMPLATE_FILE="_init.php" PW_USER_AUTH_SALT=d5e3ac4beda1e382255bbd8744d7e815 PW_LOCALE="en_US.UTF-8" PW_TIMEZONE="America/Los_Angeles" PW_DEFAULT_ADMIN_THEME=AdminThemeUikit PW_INSTALLED=1580675413 PW_HTTP_HOSTS = "domain.com,www.domain.com" # Some API that is used EXTERNAL_SERVICE_API_URL="https://api.someservice.loc/v2" # Development EXTERNAL_SERVICE_API_KEY=0d41fe1b68244f4ea51ae5e4abd24fab # Mailgun MG_KEY=key-192cde47ab73095e747ebe7556577b2d MG_DOMAIN="mg.somedomain.com" # Forecast.io FORECAST_IO_KEY=c28096383d66bcb1e2cb9ec37153f85c To take the idea further, it could be integrated with the ProcessWire API in a way that would prevent conflicts, keep .env variable naming organized, and make any value added by the developer available. Something like: <?php // An accessor method, this is probably the cleanest and resembles other frameworks $config->env('SOME_ENV_VARIABLE'); // Nested under a property acting as a namespace $config->env->SOME_ENV_VARIABLE; // On ProcessWire projects I implement some extras to easily interact with .env values without needing to access them directly. $config->envIs('production'); // boolean I haven't built a ProcessWire site without implementing this for many years and there's a great widely-used great package that provides .env values to PHP. There are also hosting providers that make environment variables/secrets manageable through their admin UI that eliminates the need for an actual file in production entirely. If ProcessWire were to implement environment variables it could look to values that may already exist and fall back to using a file. Implementation aside, if someone is able to access phpinfo() in production it's a critical issue beyond exposing config values given the totality of information dumped by that function.1 point
-
Hello ProcessWire community, it's been a while since I last shared a project showcase with you all ? Today, I'm excited to present a recent project we've been working on: The website of the Austrian artist Tanja Boukal - www.boukal.at This project has been an interesting journey, and I'm excited to highlight some of the features and solutions we implemented: First off, I had to make the project run on my local development computer. That was quick and easy thanks to DDEV, where you can easily define the setup in a simple yaml file (eg php7.4, mariadb 10.2, etc) and then update the setup to a current one and see what breaks and then apply all updates ? Then, we tackled the challenge of cleaning up everything from the old ProcessWire website (not done by me). The page was quite a mess. I'm not blaming anybody for that, but I guess we all know the problem: The developer has some structure in his/her had and it works great at the beginning. But then the real world kicks in and slightly different needs pop up here and there and quickly the initially planned structure is not sufficient any more. We need a gallery on a page we didn't plan upfront, or we need some additional text above or below some other elements where we don't have Inputfields... So the client ended up creating several pages on the root level to be able to input the desired content and then link wildly to those hidden pages. Actually I think she did a great job, because she got things done without needing help from a developer (which costs money as we all know). During that process and thanks to RockPageBuilder we got rid of many unnecessary templates while providing the client with a lot more flexibility than before ? Before the relaunch: After the relaunch (with AdminStyleRock for styling the backend in the client's colors): Not only was the content on the old PW site structured completely different than on the new one, we also had two WordPress blogs that had been around that we wanted to integrate into the new website. Both RockShell and RockFrontend's DOM-Tools where extremely helpful in that process! We even used @FireWire great Fluency module to translate imported blog posts on the fly! This command is simply put into /site/modules/Site/RockShell/Commands/ImportAegean.php and will then instantly be available to RockShell as import:aegean command ? And then you can run "rockshell import:aegean", watch it do its work and enjoy ? Another pain for the client was that many people in the arts industry still rely on printed information. So she wanted to provide all the information about her work not only on her website but also as downloadable PDFs. On the old website this process was all done manually and whenever she had a new work/catalogue/project to share she had several things to update. Now she only updates that information on one place and RockPdf creates an updated PDF for her - with all entries sorted automatically by date ? As mentioned RockPageBuilder adds a lot of flexibility to the website and makes editing content easier than ever before: But that's not a one-way-road! Where necessary we can still provide a more rigid structure and add custom fields that show up at dedicated places not movable by the client - for example date, cover-picture and teaser-text that should show up on all blog pages at the very top and at the exact same place: After that identical header section the client is free to choose from all available content elements like regular text, downloads or youtube videos (fully gdpr compliant without the client thinking about that). The work section showcases her artworks, projects, exhibitions and catalogues. All are linked to each other with the great ConnectPageFields module. So for example the https://www.boukal.at/work/projects/the-aegean-project/ has several other pages connected and also has its own blog! Ah, every aspect of the website is multilingual, which is also cool and where ProcessWire shines once more - especially with one-click-translations thx to Fluency! Another nice feature is that the page shows indicators for external links: This is a CSS-only solution and quite easy to implement (using LESS syntax): // style external links with icon body > *:not(#tracy-debug):not(.no-icon) { a[href^="http://"]:not([href*="www.boukal.at"]):not(.no-icon):after, a[href^="https://"]:not([href*="www.boukal.at"]):not(.no-icon)::after { content: url("/site/templates/images/external-link.svg"); display: inline-block; position: relative; top: 3px; margin-left: 5px; } } The site has top-notch performance thanks to the brilliant ProCache module and we did do some basic lighthouse optimisations! Hosting is done by me as well and for quality assurance we are monitoring all services with uptime kuma including a monthly report built again with RockPdf ? I find it quite funny that these 6 spikes show loading times of around one second - that's less than the loading time of an average website! All other checks finished within < 100ms (from the same data center). The spikes happen when content is updated and ProCache has to rebuild the static copy of the homepage showing how much of a difference this treasure makes thx to Ryan ? Site statistics are collected using Matomo to provide a great user experience without an annoying cookie banner. Consent for Youtube videos is requested on demand when a video is clicked on. Last but not least all the code is under version control and changes are pushed to the live server simply by doing a git commit (using RockMigrations deployment tools): So once the client requests a change and I'm done with the update I simply do a "git push" and GitHub does the rest and two minutes later the changes are live ??♂️ I hope you enjoyed reading and I hope you like the site as much as we do ? I'm happy to hear what you think and if you find something to improve please let us know! ? PS: If you like what you see and want to push your next project to the next level I'm happy to do consulting on an hourly basis so that you can efficiently pull my 10 years of ProcessWire knowledge into your work ? Let's meet at cal.baumrock.com - always happy to see real faces instead of avatars ?1 point
-
Happy to announce the launch of the completely rebuilt San Francisco Contemporary Music Players website, using ProcessWire. https://sfcmp.org/ The previous website was a hornet's nest of disorganized content, dozens of 3rd party plugins, duct taped together within WordPress... difficult to use, time consuming and confusing to manage. And didn't look so good either. Lot of fun to rebuild this, though took several months. YOOtheme Pro and UiKit were a dream for me to work with, just love those. Made it so possible to create all of the custom sections, widgets, sliders, cards, mega menus, and so on. Don't consider myself a front-end focused web dev, so have a deep appreciation for the time, care and effort that Yoo has put into both UiKit and YOOtheme Pro. Almost no additonal CSS was needed to be written for this; the stock UiKit classes and attributes make it possible to just build things in HTML and not have to fiddle with CSS. Ryan's commercial modules played a major role in the build. ProFields, ListerPro, ProCache, and FormBuilder were all important. FormBuilder+Stripe allowed me to confidently migrate their need for a stripe checkout from some WP plugin to the clean and simple setup now using FB. ( https://sfcmp.org/donate/print-for-sale-dirge-by-hung-liu/ ) Some libraries also were of great use and value, namely PLYR for audio, and tabulator for some table display type of stuff. As always, the API was a dream to work with, many custom import scripts were created along the way to import legacy Press, Albums, Repertoire works, Program Booklets library, Players etc.. The image API is doing wonders with SRC sets, and webp images. The PW documentation site was a daily companion. This forum likewise was always a most valuable and enjoyable resource to search and rely on for solving the occasional conundrum. There is such a wealth of info here that i never found it necessary to post a question. Lastly, to underscore just how unparalleled, flexible and user-friendly the PW backend is, we had the backend training session a couple of weeks after the site was launched, and within 30 minutes, the person who will be managing the content was able to know how to create and manage concerts, blog posts, albums, press articles and more.1 point