Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/19/2019 in all areas

  1. I was moving recently my sites made with Eleventy to Netlify (free plan) and I really like it. It's easier to deploy (just push to GitHub) and as a plus I have a version control which was not the case with my previous projects. I noticed that my site scores higher on YSlow on GTMetrix so I went ahead and fixed the remaining issues it was complaining about. Previously I used no CDN so YSlow was always lagging behind the PageSpeed score. The result is 100/100, and not only the main indicators but all recommendations below them (it was 100/100 even if one or two recommendations were only 99%). I know it's an overkill and it really doesn't add extra value to the site, but I was curious whether it is possible to reach such figures. Apparently is ? https://gtmetrix.com/reports/neptunbrigad.hu/ffOeMHHL
    6 points
  2. Hi all, wanting to modify the CSS of a core module (JqueryMagnific in my case), but not to touch the files in \wire\, I found this older blog entry: https://processwire.com/blog/posts/processwire-core-updates-2.5.14/#multiple-copies-of-the-same-module That might be helpful for others, too. (It's pure fun using PW!)
    5 points
  3. Thanks for noticing it. I usually place those overrides in /site/wire/ (for example /site/wire/JqueryMagnific) so I know which module is an override from the directories structure.
    5 points
  4. Hi everyone. Lots of new stuff this morning. 1) Terminal panel (available in a panel and also as a dedicated Process module - similar to how the Adminer feature is set up) NOTE: It does not support interactive commands like vi, nano, apt, etc. DO NOT attempt to use these as they may result in you needing to restart apache. This is a bash terminal that lets you quickly execute commands on a server. In addition to normal commands like: ls, cd, cat, mkdir, rm, chmod, chown, etc, you can also do mysql command line calls which is very handy if you need to add a new user, create a mysqldump etc. Note that for mysql commands you need to issue them individually - you can't simply start "mysql" and issue commands from there - each call needs to include your username and password and the command to be run, eg: mysql -u root -p mypassword -e "CREATE DATABASE newtablename"; There is also an upload and download command, eg "upload test.txt" which will spawn a file selector dialog on your machine to upload that file to your server with the given name. It also has arrow up and down for command history as well as tab autocompletion of commands and file names. 2) Lots of new filterbox implementations @tpr has again put in lots of work to implement filterbox on the APIExplorer, Captain Hook, and PHPInfo panels - these will be super helpful to search through these complex panels. I have also added a ALT+F shortcut to get your cursor into the Find input for all these panels. Let us know how these new features work out for you. Cheers!
    5 points
  5. A small news about Duplicator. There is a work in progress on a development version (v1.3.10-ATO) - nothing which can harm your server and could be already tested on different setup. You can download this dev version on GitHub : https://github.com/flydev-fr/Duplicator/archive/dev.zip or at the end of this post. The module still contain minor issues but the overall processing is faster than before and packages can be built and restored as well. Thanks to @Autofahrn for putting his hand in the module! Autofahrn also added a great feature which give the possibility to exclude file through regular expression. Also, image variations created by ProcessWire are now excluded by default. Duplicator-dev-1.3.10-ATO.zip
    4 points
  6. Here is GoodKidsClothes.com, a blog about kids clothes - news, style tips, sale alerts, and more. GoodKidsClothes.com originally ran on Wordpress, and I moved it to Processwire recently, the new Processwire version is shown above. There was a fair amount to change over, since it had 4 years on Wordpress before switching! I kept the colors, background, etc in line with what it had been before - a soft, friendly look. I wasn't seeking for it to be identical to its previous appearance, just similar but updated/better/more fun. The html I did from scratch, although I used the W3CSS framework. I love W3CSS because they handle all the responsive breakpoints, and the default styling is a clean flat modern look with plenty of great pre-sets. The reason I moved this site over to ProcessWire was not looks but actually functionality: the new Wordpress editor (Gutenburg) had just come out - one of its quirks is that it couldn't keep up with my typing, so I had to literally slow down my typing, which really defeats the purpose of WP as a blogging CMS. (Processwire's editor keeps up with me just fine). Also it was anyway time for me to manually go through and update old articles, put in new affiliate links etc, so I decided to do everything all at once and switch over to ProcessWire. In case anyone is wondering, the switch-over was manual since I was going to examine every article I'd written to either a) update it, b) move it to another of my sites, or c) trash it. This was not time-efficent but this way I wound up with being certain everything was up to date content-wise, plus no unwanted bloat (like extra WP fields) could make its way into my Processwire database. I simply installed Processwire via 1-click Softaculous install in a subdirectory of the original Wordpress site, with the original site still running. Then after I had the Processwire version fully finished (this took several weeks), I simply uninstalled the Wordpress version and moved the Processwire site into the document root. This way I had less than 1 minute downtime. UX/UI The first menu link is an all-abilities-inclusive version of "skip to content". The actual text displayed depends on which page template is being used ( this text is assigned in _init). For example, the Article template will display "Scroll to article", while Search Results template will display "Scroll to results". Link styling in the body of article content is designed for both the desktop and mobile user, with simultaneous underlining and highlighting showing the entire link region to aim for when tapping on mobile. On the home page and some other templates as needed, skip links are available within the page. They offer the option to skip past a series of links such as social sharing links, pager navigation, etc for a) the screen reader user and b) the fully-sighted keyboard-only user (no mouse). These links only become visible to the eye when focus comes upon them via tabbing. Tab through the home page to see it in action - this is the template where the most skip links have been needed. Cookie manager - originally I used a slider for turning Google Analytics tracking on/off but changed to checkbox because I could not work out a way to manipulate slider without mouse. Newsletter - field, and feed One feature of this site is its newsletter, and you'll see here how Processwire shines. The setup was (and still is) that on days when a new blog post relevant to children's clothes is published, subscribers get a brief email notifying them of the new article and linking to it. This is all handled by MailChimp, which I highly recommend. Under the old Wordpress system, I had to use categories to classify which of the posts wound up going into the newsletter (kids clothes) and which posts didn't (other topics like parenting etc). There was always the chance that under default WP behavior, things would be classified incorrectly if I forgot to specify categories. Under Processwire, I've set up the article template to have a field called "Newsletter" which is a simple drop-down choice of "For newsletter" or "omit from Newsletter". There is no default value, and it's a required field, ensuring that I do remember to specify it one way or another. It's such a relief to do it this way! My newsletter feed was easy to customize under Processwire: I created a feed template that selected a) all the pages using the article template that also had b) the "For newsletter" field selected, and those are listed at /newsletter in feed format. Please note that this feed may be empty right now - I omitted my existing articles from newsletter feed as subscribers have already seen them, and haven't had time to write new articles yet. To clarify, I'm expecting the newsletter feed at /newsletter to only ever be read by MailChimp, although it's certainly possible to be used by feed readers or read by humans. XML sitemap Under Processwire, I was able to generate a list of articles in XML format at /sitemap.xml that I can then submit to Google as the XML sitemap for this site. Best of all, unlike web-based crawler-type sitemap generators which generate a static sitemap that you then upload to the document root, my Processwire /sitemap.xml auto-generates each time the page is loaded, so it's always auto-updated - any changes in back office like article deletion, unpublishing, adding new articles etc are reflected automatically in /sitemap.xml. Some advantages of Processwire features when templating 1. _init.php file - my theme was designed for subsequent use in my other sites, so selected pages for use in nav menu (About, Privacy Policy) are automagically "found" in _init.php as follows: $pp = $pages->findOne("template=BN-infopage, sort=created, title*=Privacy"); $ab = $pages->findOne("template=BN-infopage, sort=created, title*=About"); 2. Made use of Processwire's built-in retina-friendly image resizing class, class="hidpi" to ensure social sharing icon links render at a decent resolution on mobile screens. Other info To check my html and to help identify problems that are not visible to the eye, I found it incredibly helpful to use the "audit" feature available on Chromium and other Chrome-based browsers. (F12->Audit-> select options you want). The order of the blogroll looks a little odd at first glance but it's ordered based purely on publication date. However, I updated some articles and they display the last updated date, which makes the blogroll look like it's not in date order even though it's in publication date order. Also some dates (the older article dates) reflect a user-specified date field, to show the article was valid at the time it was written (e.g. time-sensitive info such as reviews, sale alerts, etc). I'd be happy to explain further if anyone's interested. Moving forward as I write more articles, there should not be an issue, since I usually update only on or very soon after the publication date, so we should not expect to see wildly different dates on sequential articles from here on in.
    3 points
  7. I can confirm that this fixed the problem for me, when I typed check_access=0 by hand into the selector field instead of copying and pasting it from Adrian's message. Thank you @adrian, for identifying the solution! And thank you, @Robin S for figuring out where I went wrong!
    3 points
  8. In your custom find, choose Custom (field=value) and enter check_access=0 in the far right column.
    3 points
  9. @jsilmarovi Or you can use URLSegments if you want to reduce the number of pages but still output different markup.
    3 points
  10. @tpr has yet again put in lots of time to improve the filtering for the APIExplorer and Captain Hook panels:
    3 points
  11. Not a completly serious tip for listening during developing, but maybe a good one for listening before starting. ? or
    2 points
  12. Hi @Troost, I see a couple of possible reasons. For one, you are displaying multiple fields in the projectoverzicht.php, are those fields from the homepage or from the projects index page? The $page variable will always refer to the current page, so if the loaded page is the homepage, ProcessWire will look for those fields on the homepage. If the projectoverzicht.php is also used as a standalone-page (for example, if you have a page https://your-domain.de/projectoverzicht), then the $page variable will refer to this page instead, so that is a possible error. Besides that, you are using the $project_index variable from my example, but it isn't declared anywhere, that will throw a critical error in PHP. Make sure to load the index page first!
    2 points
  13. If you post the template code that you have so far it will be easier to point you in the right direction. Anyway, in order to loop over the projects in your homepage template, you'll want to (1) get the projects index page, (2) find all children with the project template and (3) render the URL and preview image field in your markup. Something like this: // use the id of your actual projects page $project_index = $pages->get(156); // use the template name of your project template $projects = $project_index->children("template=project"); echo '<ul>'; foreach ($projects as $project) { echo '<li>'; echo '<a href="' . $project->url() . '">'; // use the field name of your preview image field echo '<img src="' . $project->preview_image->url() . '" alt="' . $project->preview_image->description() . '">'; echo '</a>'; echo '</li>'; } echo '</ul>';
    2 points
  14. I wouldn't even think about such an invitation for performing dangerous things through a regular get request like invoking "any" templatefile. If you wish to generate different output depending on a get parameter you are of course free to do so (there is $input->get() to easily retrieve get parameters). Just call a function or execute another conditional block in your template.
    2 points
  15. Just in case, you love the module as much as i do ... and you think it looks a bit old fashioned. I did a little styling update (just the css and a few fether svg icons): To use it just put the attached files to site\modules\AdminBar @Apeisa: You may apply this to the original module if you like! AdminBar.zip
    2 points
  16. I think it is amazing that you took to writing a tutorial for us this early in your involvement with the community. Good job amigo ?
    2 points
  17. This kind of selector is working for me with superuser and non-superuser roles. Did you type the "check_access=0" into the selector string by hand or did you copy/paste from @adrian's post? Because I'm seeing non-printable characters when pasting from the post: @Pete, this non-printable character issue is getting quite bad in the forums lately and can cause a lot of confusion. I don't understand how these characters are creeping into posts seeing as I'm sure nobody is entering them deliberately. Do you know if anything can be done to avoid this issue?
    2 points
  18. I've been working with ProcessWire for a while now, and I've noticed that using Composer to manage dependencies and autoload external libraries isn't as prevalent in ProcessWire development as in other areas of PHP programming. I started out by using the default setup recommend in this blogpost. However, one major problem I have with this approach is that all external dependencies live in the webroot (the directory the server points to), which is unfavourable from a security standpoint and, in my opinion, just feels a bit messy. In this tutorial, I want to go through a quick setup of Composer and ProcessWire that keeps the dependencies, all custom-written code and other source material outside of the webroot, and makes full usage of the Composer autoloader. This setup is pretty basic, so this tutorial is probably more useful to beginners (this is why I'll also include some general information on Composer), but hopefully everyone can take something away from this for their personal workflow. Site structure after setup This is what the directory structure can look like after the setup: . ├── composer.json ├── composer.lock ├── node_modules │ └── ... ├── public │ ├── index.php │ ├── site │ ├── wire │ └── ... ├── packacke-lock.json ├── package.json ├── sass │ ├── main.scss │ ├── _variables.scss │ └── ... ├── src │ ├── ContentBag.php │ └── ... └── vendor ├── autoload.php ├── composer ├── league ├── symfony └── ... As mentioned, the main point of this setup is to keep all external libraries, all other custom source code and resources out of the webroot. That includes Composer's vendor folder, your node_modules and JavaScript source folder if you are compiling JavaScript with webpack or something similar and including external scripts via NPM, or your CSS preprocessor files if you are using SASS or LESS. In this setup, the public directory acts as the webroot (the directory that is used as the entry point by the server, DocumentRoot in the Apache configuration). So all other files and directories in the mysite folder aren't accessible over the web, even if something goes wrong. One caveat of this setup is that it's not possible to install ProcessWire modules through Composer using the PW Module Installer (see Blogpost above), but that's just a minor inconvenience in my experience. Installation You'll need to have composer installed on your system for this. Installation guides can be found on getcomposer.org. First, open up your shell and navigate to the mysite folder. $ cd /path/to/mysite/ Now, we'll initialize a new Composer project: $ composer init The CLI will ask some questions about your projects. Some hints if you are unsure how to answer the prompts: Package names are in the format <vendor>/<project>, where vendor is your developer handle. I use my Github account, so I'll put moritzlost/mysite (all lowercase). Project type is project if you are creating a website. Author should be in the format Name <email>. Minimum Stability: I prefer stable, this way you only get stable versions of dependencies. License will be proprietary unless you plan on sharing your code under a FOSS license. Answer no to the interactive dependencies prompts. This creates the composer.json file, which will be used to keep track of your dependencies. For now, you only need to run the composer install command to initialize the vendor directory and the autoloader: $ composer install Now it's time to download and install ProcessWire into the public directory: $ git clone https://github.com/processwire/processwire public If you don't use git, you can also download ProcessWire manually. I like to clean up the directory after that: $ cd public $ rm -r .git .gitattributes .gitignore CONTRIBUTING.md LICENSE.TXT README.md Now, setup your development server to point to the /path/to/mysite/public/ directory (mind the public/ at the end!) and install ProcessWire normally. Including & using the autoloader With ProcessWire installed, we need to include the composer autoloader. If you check ProcessWire's index.php file, you'll see that it tries to include the autoloader if present. However, this assumes the vendor folder is inside the webroot, so it won't work in our case. One good place to include the autoloader is using a site hook file. We need the autoloader as early as possible, so we'll use init.php: EDIT: As @horst pointed out, it's much better to put this code inside the config.php file instead, as the autoloader will be included much earlier: // public/site/config.php <?php namespace Processwire; require '../../vendor/autoload.php'; The following also doesn't apply when including the autoloader in the config-file. This has one caveat: Since this file is executed by ProcessWire after all modules had their init methods called, the autoloader will not be available in those. I haven't come across a case where I needed it this early so far; however, if you really need to include the autoloader earlier than that, you could just edit the lines in the index.php file linked above to include the correct autoloader path. In this case, make sure not to overwrite this when you update the core! Now we can finally include external libraries and use them in our code without hassle! I'll give you an example. For one project, I needed to parse URLs and check some properties of the path, host et c. I could use parse_url, however that has a couple of downsides (specifically, it doesn't throw exceptions, but just fails silently). Since I didn't want to write a huge error-prone regex myself, I looked for a package that would help me out. I decided to use this URI parser, since it's included in the PHP League directory, which generally stands for high quality. First, install the dependency (from the project root, the folder your composer.json file lives in): $ composer require league/uri-parser This will download the package into your vendor directory and refresh the autoloader. Now you can just use the package in your own code, and composer will autoload the required class files: // public/site/templates/basic-page.php <?php namespace Processwire; use \League\Uri\Parser; // ... if ($url = $page->get('url')) { $parser = new Parser(); $parsed_url = $parser->parse($url); // do stuff with $parsed_url ... } Wiring up custom classes and code Another topic that I find really useful but often gets overlooked in Composer tutorials is the ability to wire up your own namespace to a folder. So if you want to write some object-oriented code outside of your template files, this gives you an easy way to autoload those using Composer as well. If you look at the tree above, you'll see there's a src/ directory inside the project root, and a ContentBag.php file inside. I want to connect classes in this directory with a custom namespace to be able to have them autoloaded when I use them in my templates. To do this, you need to edit your composer.json file: { "name": "moritzlost/mysite", "type": "project", "license": "proprietary", "authors": [ { "name": "Moritz L'Hoest", "email": "info@herebedragons.world" } ], "minimum-stability": "stable", "require": {}, "autoload": { "psr-4": { "MoritzLost\\MySite\\": "src/" } } } Most of this stuff was added during initialization, for now take note of the autoload information. The syntax is a bit tricky, since you have to escape the namespace seperator (backslash) with another backslash (see the documentation for more information). Also note the PSR-4 key, since that's the standard I use to namespace my classes. The line "MoritzLost\\MySite\\": "src/" tells Composer to look for classes under the namespace \MoritzLost\MySite\ in the src/ directory in my project root. After adding the autoload information, you have to tell composer to refresh the autoloader information: $ composer dump-autoload Now I'm ready to use my classes in my templates. So, if I have this file: // src/ContentBag.php <?php namespace MoritzLost\MySite; class ContentBag { // class stuff } I can now use the ContentBag class freely in my templates without having to include those files manually: // public/site/templates/home.php <?php namespace Processwire; use MoritzLost\MySite\ContentBag; $contentbag = new ContentBag(); // do stuff with contentbag ... Awesome! By the way, in PSR-4, sub-namespaces correspond to folders, so I can put the class MoritzLost\MySite\Stuff\SomeStuff in src/Stuff/SomeStuff.php and it will get autoloaded as well. If you have a lot of classes, you can group them this way. Conclusion With this setup, you are following secure practices and have much flexibility over what you want to include in your project. For example, you can just as well initialize a JavaScript project by typing npm init in the project root. You can also start tracking the source code of your project inside your src/ directory independently of the ProcessWire installation. All in all, you have good seperation of concerns between ProcessWire, external dependencies, your templates and your OOP-code, as well as another level of security should your Server or CGI-handler ever go AWOL. You can also build upon this approach. For example, it's good practice to keep credentials for your database outside the webroot. So you could modify the public/site/config.php file to include a config or .env file in your project root and read the database credentials from there. Anyway, that's the setup I came up with. I'm sure it's not perfect yet; also this tutorial is probably missing some information or isn't detailed enough in some areas depending on your level of experience. Feel free to ask for clarification, and to point out the things I got wrong. I like to learn as well ? Thanks for making it all the way to the bottom. Cheers!
    1 point
  19. I thought it might be good to have a place where we can post other good CMSs and transparently talk about their positive aspects and, why not, compare them to PW. This might help PW grow by learning with the others, and hopefully, could even bring those tools devs to explain them to us. This idea came up to me after this discussion, and from realizing that after discovering PW I'm not as curious about finding other CMSs as I was before. I can Imagine that this has also happened to others here, and can never be good to stay in ignorance I almost stopped looking for other CMSs, but there are two that I would like to share for starting: The Secretary -> http://www.secretarycms.com/ (this is a free self hosted portfolios CMS. For a portfolios tool it's quite flexible. The user interface is also nice) Webpop -> http://www.webpop.com/ (It's a cloud CMS that gives complete control over the markup. This one is not free)
    1 point
  20. Here I'm writing up about my first ProcessWire site, Reached.space, a blog and directory about shops which offer international shipping. I'm from The GrayFly Group, which is the registered trade name for GrayFly Stationery, LLC, a limited liability company registered in the state of Kentucky, USA. You might ask, why is a stationery company creating websites?! Well, in a way both activities are very similar: both activities have the goal of getting written messages across in a pleasing manner to the reader. With that out of the way, let's move on and explain what went on behind the scenes of the Reached.space site: Template I used a free CSS-based template from W3CSS at https://www.w3schools.com/w3css/w3css_templates.asp , using mainly the "Architect" template as the basis and modifying it as needed. Pagination The pagination feature of ProcessWire was very helpful here; I kept the home page to just two blogroll articles so that the reader was not overwhelmed, but upon pressing "more articles" the remainder of the blogroll is paginated with 4 articles to a page. Screen reader I made adjustments to my usage of the template to make it screen-reader-friendly. I used the Google Chrome extension to test out how the site would be handled with a screen reader. Security Security is always important, so I was thrilled to find a great all-in-one-place security guide in the ProcessWire docs at https://processwire.com/docs/security/ - I simply went through the guide and did what it said, using it as a checklist. Modules As far as I'm aware, the only additional modules I used (that were not already activated by default in standard PW install) were the Upgrade and Upgrade Checker modules. The main reason for this was security considerations, but it was also an added convenience and peace of mind to have it check for updates every time I logged in. However, I did use additional software that was not modules, as described below. Other software - Simple HTML DOM Here I was very fortunate to receive help from the ProcessWire community on the forum. Due to the site's monetization model being affiliate marketing, I wished to make all my external links nofollow and target _blank by default. User @Robin S was instrumental in showing me how to do this using Simple HTML DOM in the forum post https://processwire.com/talk/topic/17295-solved-how-to-make-external-links-nofollow-and-target-_blank-by-default-if-using-source-code-toggle-in-editor/ Other software - Google Analytics cookie manager My site requirements for GDPR were specific enough that I felt I would rather develop my own code to handle Google Analytics tracking, which I'll describe here. I wanted to be certain GA tracking was disabled by default requiring opt-in, instead of opt-out. I also included in the Cookie Manager some written info about third party cookies (these are placed when clicking on affiliate links) and how the user can avoid such tracking (turn off third party cookies in their browser settings). I also disabled front-end PW cookies as described here: https://processwire.com/talk/topic/15270-session-storage-and-lifetime/ Google Analytics cookie settings The Google Analytics cookie setting code was done using JavaScript. I used a session storage variable to indicate whether the user had a) accepted GA tracking cookies b) declined them or c) had not made a choice yet. I also had to make some changes also to the <head> code to ensure Google Analytics cookies were not set unless the user had accepted them. Efficiency - optimizing 404s I used the guide at https://processwire.com/blog/posts/optimizing-404s-in-processwire/ to sinkhole bot-driven 404 requests to a static 404 file. Back office pic Below is an image of how ProcessWire allows helpful field descriptions and displays them when used in templates, so that when I come to actually use or enter content in fields I created months ago, I know what the ramifications are. Very helpful. Also, when using the back office I found the Reno admin theme to be very pleasing, efficient, and easy to use.
    1 point
  21. Edit: Because of the great response to this topic I wrote a guest blogpost: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ One of the hidden treasures of processwire seems to be the creation of custom admin pages. Technically speaking those pages are ProcessModules - but i guess that's the reason why so many people out there seem to be afraid of building them... it sounds so hard! You've never created a module for ProcessWire? You have never created a plugin for any other CMS? You have no clue about OOP with all its classes, methods and properties? No problem! I'll show you how simple you can start: <?php class CustomAdminPage extends Process { public static function getModuleinfo() { return [ 'title' => 'Custom Admin Page Example', 'summary' => 'Minimalistic ProcessModule to show that nobody has to be afraid of building custom admin pages.', 'href' => 'https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/', 'author' => 'Bernhard Baumrock, baumrock.com', 'version' => 1, // page that you want created to execute this module 'page' => [ 'name' => 'customadmin', // your page will be online at /youradmin/setup/customadmin/ 'parent' => 'setup', 'title' => 'Custom Admin Page Example' ], ]; } public function ___execute() { return 'This is the most simple Admin-Page you have ever seen :)'; } } Now save this file as CustomAdminPage.module and place it in your /site/modules folder. After a refresh it will show your module in the modules manager of your site where you can install it: After installation you already have your first very own admin page! Congratulations! Was not too hard, was it? It's as simple as that! Now lets add some more custom HTML. And to show you another nice feature we will add this code to a separate method called executeDemo(). And because everything is so simple we will also add some javascript to this page public function ___executeDemo() { $out = ''; $out .= '<h1>H1 has some special css styling in the admin, thats why it seems to have no effect</h1>'; $out .= '<h2>H2 looks different ;)</h2>'; $out .= '<h3>...and so does H3</h3>'; $out .= '<button onclick="myFunction()">Click me</button>'; $out .= '<script>function myFunction() { alert("this is a demo javascript"); }</script>'; return $out; return ''; } Now thanks to ProcessWire-magic your page will already have its own URL: Just append /demo to your url and see what you get: And of course don't forget to click the button Ok, now that code looks a bit hacky, right? Inputfields and especially InputfieldMarkup for the win! We add another method with some advanced code. To use inputfields we need a form that holds all those inputfields and that makes it possible to handle user input lateron. See somas great tutorial about forms here for a quickstart and more details: public function ___executeAdvanced() { $out = '<h2>A more complex Example</h2>'; $form = wire()->modules->get('InputfieldForm'); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Markup Test 1'; $field->value = '<h1>h1</h1><h2>h2</h2><h3>h3</h3><h4>h4</h4>'; $form->add($field); $out .= $form->render(); return $out; } Ok, it get's boring Let's do something more fun and add a chart in a second field and change the fields to 50% screen width (I'm sure you know that already from the GUI template editor)! public function ___executeAdvanced() { $out = '<h2>A more complex Example</h2>'; $form = wire()->modules->get('InputfieldForm'); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Markup Test 1'; $field->value = '<h1>h1</h1><h2>h2</h2><h3>h3</h3><h4>h4</h4>'; $field->columnWidth = 50; $form->add($field); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Chart Sample'; $field->value = '$chart'; //$field->notes = 'Example code taken from here: http://www.chartjs.org/docs/latest/getting-started/usage.html'; $field->columnWidth = 50; $form->add($field); $out .= $form->render(); return $out; } OK, we are almost there... we only need to add the chart library! To keep everything clean we will put the code for the chart in another method. We will make that method PRIVATE to add some security. Our new Method: private function renderChart() { // prepare chart code wire()->config->scripts->add('https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js'); ob_start(); ?> <canvas id="myChart"></canvas> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255,99,132,1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); </script> <?php return ob_get_clean(); } Now we just need to call $this->renderChart() in the right place! Here is the complete Module: <?php class CustomAdminPage extends Process { public static function getModuleinfo() { return [ 'title' => 'Custom Admin Page Example', 'summary' => 'Minimalistic ProcessModule to show that nobody has to be afraid of building custom admin pages.', 'href' => 'https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/', 'author' => 'Bernhard Baumrock, baumrock.com', 'version' => 1, // page that you want created to execute this module 'page' => [ 'name' => 'customadmin', // your page will be online at /youradmin/setup/customadmin/ 'parent' => 'setup', 'title' => 'Custom Admin Page Example' ], ]; } public function ___execute() { return 'This is the most simple Admin-Page you have ever seen :)'; } public function ___executeDemo() { $out = ''; $out .= '<h1>H1 has some special css styling in the admin, thats why it seems to have no effect</h1>'; $out .= '<h2>H2 looks different ;)</h2>'; $out .= '<h3>...and so does H3</h3>'; $out .= '<button onclick="myFunction()">Click me</button>'; $out .= '<script>function myFunction() { alert("this is a demo javascript"); }</script>'; return $out; return ''; } public function ___executeAdvanced() { $out = '<h2>A more complex Example</h2>'; $form = wire()->modules->get('InputfieldForm'); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Markup Test 1'; $field->value = '<h1>h1</h1><h2>h2</h2><h3>h3</h3><h4>h4</h4>'; $field->columnWidth = 50; $form->add($field); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Chart Sample'; $field->value = $this->renderChart(); $field->notes = 'Example code taken from here: http://www.chartjs.org/docs/latest/getting-started/usage.html'; $field->columnWidth = 50; $form->add($field); $out .= $form->render(); return $out; } private function renderChart() { // prepare chart code wire()->config->scripts->add('https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js'); ob_start(); ?> <canvas id="myChart"></canvas> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255,99,132,1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); </script> <?php return ob_get_clean(); } } I hope you enjoyed reading this and it will open up many new possibilities for you! Updates: permissions: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/?do=findComment&comment=174746 tutorial on file uploads: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/?do=findComment&comment=185261 snippet how to use NavJSON: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/?do=findComment&comment=216412
    1 point
  22. From time to time, I copy/paste snippets of code in the forum here to my editor (SublimeText). Unfortunately, I think the forum software sometimes throws in invalid, INVISIBLE unicode characters that break the copied code and usually will throw PHP errors that at first sight don't make any sense. These characters are impossible to detect in SublimeText, but with the following plugin I just discovered, it will identify them: https://packagecontrol.io/packages/Gremlins
    1 point
  23. I've finally managed to to remove my 1.5 decades old, all-ugly, frame-based photography site to something more modern. So what looked like this for a much too long time: now present the images much better, has a consistent layout and finally is responsive: The intention of the site is to provide some inspiration for the ambitious photographer and also provides a tips section focusing on some aspects of digital photography. After being idle for too long, I feel new motivation for adding even more tips as time allows. We'll see. https://www.tofahrn-foto.de/en/ Layout is basically pure UiKit and all content (including menu and footer) is managed using my RepeaterFlex as a kind of real world test. The RepeaterFlex is inspired by the commercial RepeaterMatrix fieldtype but uses plugins to define item templates (in case you're interested, there is a small Demo Site for RepeaterFlex including some documentation). The site uses lazy load of images (lazysizes.js) and page transistions (barba.js V1) to obtain a hopefully smooth experience. There also is ProCache running to deliver minimized css and markup. Enjoy.
    1 point
  24. That's on my list to learn as I'm learning Angular at the moment. Strapi looks like the most interesting one I could find. https://www.capterra.com.au/software/170599/strapi
    1 point
  25. Has any one here used a JavaScript based CMS, assuming such a thing exists? If so, can they share their experiences with it? I"m thinking about doing a small project using a JS based CMS to improve my JS/TS skills
    1 point
  26. It's the onInit callback where you can return false, eg. based on the number of DOM elements. That's nice ?
    1 point
  27. Yes, I have some hundred users (800 atm) and I need to switch to all of them
    1 point
  28. @adrian FYI it is possible to load filterbox only if some criteria is meet, eg. the number of data to filter is greater than 20.
    1 point
  29. I expect it would work ok, but I am wondering if you actually have that many users you need to switch to. Have you considered making use of the Restricted Roles option in the User Switcher settings? If that doesn't suit your needs and filterbox really is needed, let me know and I'll take a look at implementing it.
    1 point
  30. Solved! Thanks to @MoritzLost <?php $project_index = $pages->get(1015); $projects = $project_index->children("template=projectdetail"); foreach ($projects as $project) { echo '<div class="col-md-4 col-sm-4 col-xs-6 fh5co-project animate-box">'; echo '<a href="' . $project->url() . '">'; echo '<img src="' . $project->projectthumb->url() . '" alt="' . $project->projectthumb->description() . '" class="img-responsive" >'; echo '<h3>' . $project->title() . '</h3>'; echo '</a>'; echo '</div>'; } ?>
    1 point
  31. @MoritzLost Thanks again for your response. I've figured it out with your lines of code. I've set some variables in my header.php. The variable from your example was later on editted in my post. I forgot to change that indeed. <?php $header = $pages->get(1018); ?> <?php $home = $pages->get(1); ?> <?php $footer = $pages->get(1019); ?> The only thing now is to get the H3 working, the rest is fine, thanks again for your support man!! ?
    1 point
  32. That's fine. In our case it was necessary to explicitly add the line in the .htaccess-file, but that should be the last solution if everything else fails. We already had a similar solution like @pmichaelis's code example to use $_SERVER if apache_request_headers fails. Maybe its more save to check for the function 'apache_request_headers' to exist: if(function_exists("apache_request_headers")) {
    1 point
  33. I don't think that one should need additional software, just to copy and use code from this forum.
    1 point
  34. Can you explain this a little more please. I just tested on a Windows machine (although pointed to a linux server), but I can't see any issues. Could you maybe put together a screencast for me demonstrating the issue? Thanks!
    1 point
  35. The modules directory is still pointing to the original. I actually thought that the original didn't work at all with recent version of PW. This is an area that I think PW really needs to work on - there are several forks which are critical updates, but are not really linked to anywhere official.
    1 point
  36. Thanks for testing @bernhard - I'll see if I can duplicate the issues you are seeing with layout - it seems fine here, but I'll test some more and see if I can try on a Windows machine. I agree that I would mostly choose a real terminal over this, but if I don't know the credentials for the server (or I am away from my computer), this is a pretty good backup, which is the way I view this feature. Regarding security - I thought through this already and here's my reasons why it's not an issue: 1) The file is not available outside the process module - PW's htaccess restrictions ensure that. 2) The process module requires superuser permission. 3) It's no more dangerous than the Console panel or Hanna code - both let you run shell_exec commands on the server anyway. This just provides a nicer interface and returns the output for you. That said, if anyone can think of a security concern that I have overlooked, please let me know.
    1 point
  37. It seems to be working, but in panel mode it's not really usable... The problem also occurs on the ProcessModule's page when I have more content than available screen space. I tried it on linux and it seems to have similar effects (eg when hitting TAB to list available directories on cd foo/bar/... But I'm not keen on this new feature. When I need a terminal, then well... I open one. Most of the time from within my IDE via ssh. I don't see a benefit of using it via tracy - but maybe that's because I don't really like working in the terminal in general ? And I'm a little worried about security aspects... even if I don't have any idea how all that new console feature works. Just saying that if I don't need this feature I'm not really happy to have it there. I uninstalled the process module, but still... the code is somewhere on the server. Maybe you can tell us a bit to make me feel more comfortable ?
    1 point
  38. @flydev For http basic auth I'd only use user/password for initial logins and for any subsequent request use some kind of token. Generally I'd support what you said about tls and intercepted requests holding any information be it a password or token, but I think more important is the fact that a user won't insert a password for each request and you don't want your app to somehow cache the supplied password. That's what should never be promoted.
    1 point
  39. @Sebi@pmichaelis Think I'm going to include @pmichaelis since it does not required additional configuration (actually before I used the RestApi Module with NGINX it was using apache_request_headers anyway)
    1 point
  40. 1 point
  41. If all of this is correct, I personally think that the stakes are too high for sending any kind of email in a place where anyone can accuse another of emailing them and subject them to thousands in penalties from a single email sent by accident. It seems like that creates a dark market for people to pursue receipt of email as a litigation model. It seems like sending any email at all is huge risk where one accidental email could bankrupt you (reminds me of the US healthcare system). Personally, I wouldn't have the ability to pay a lawyer to even respond to such a complaint, so would be inclined to play it safe and simply remove email as a communications method from my business entirely. I don't think you could safely run a software like this one (IP.Board) with those kinds of restrictions. But as far as ProMailer goes, if people subject to those kinds of laws still want to use it, I do think I can support much of what's been mentioned so far. Actually I think it's a good opportunity for ProMailer as a product to provide answers for these kinds of needs, and would enjoy implementing solutions for them. But I consider everyone here my friends, and with the stakes being so high, I would prefer that friends dealing with such laws stay far away from any software or service involved in sending email. Sending email sounds like a death trap as dangerous as swimming with crocodiles. I understand some will take the risk anyway, so I'll do my best to make sure ProMailer has answers for these kinds of things. The only one I'm really not wild about is encrypting email addresses, just because that would place major limitations on the ability to search subscribers, which might increase the risks in other ways. For instance, Mike sends you a C&D letter, but you can't find Mike in your lists in order to remove him, so he ends up getting another email, and BAM, Mike gets to take over your life savings. But I think I can provide hooks for those that want to do it anyway. In my development version, this morning I added an option to log IP addresses with subscribe request and confirmation logs. It's off by default, but can be enabled in the module settings. As I understand it logging of IP addresses is not legal in some places, so anything that has potential to record IPs I usually keep disabled as a default. But the option will be there for those that want to enable it. With regard to a blacklist, we've been talking about it in the ProMailer board and I'm currently thinking a blacklist might be better supported in the core WireMail rather than just in ProMailer. That way you could blacklist an email address for anything in PW that might send an email via WireMail, rather than just ProMailer. For instance, modules like LoginRegister use WireMail to confirm account creation, so a lower-level blacklist could affect that module or any others too, in addition to ProMailer. That way an errant confirmation email or password-reset email won't cause someone to lose their retirement savings. I understand one of these blacklists can be individual email addresses, or entire domains, but am wondering about scale: are blacklists usually fairly small, or might it be an existing published list with thousands of domains/emails?
    1 point
  42. I realize I never updated about this, sorry. It was all OK in the end - I reached out to Ryan, and it just looked like something had slipped through the cracks - my submission was made around the time that they changed they layout of the PW site directory. It got added in fine after I resubmitted. Thanks all for the input!
    1 point
  43. Please consider it a preconfigured option. We know cases where users refuse to ackknowledge that they registered and then sued for spam. It really is insane and a big business for the law industry. It would help, if ProMailer can provide as much evidence as possible (while it is totally clear, that there is no bullet proof evidence). I feel, that there is quite a culture clash between USA and in particular Germany regarding data privacy. You may run this through google translate: https://www.e-recht24.de/news/marketing-seo/7980-newsletter-a-co-double-opt-verfahren-in-muss-dokumentiert-werden.html
    1 point
  44. There is actually one benefit: if data is stored encrypted and the key is stored separately, even if it's on the same server, someone gaining illegitimate access to just your database but not full access to the server would mean that said data could be considered much less useful to the offending party. At the very least it could take them a long time to figure out what it is that they actually got their hands on. Although this predates GDPR, in opinion 03/2014 the Article 29 Working Party stated that breach affecting only encrypted data may also mean that the source of the breach isn't subject to typical breach notification procedures: Just something to consider. I'm personally still not convinced that storing emails encrypted makes a whole lot of sense on a typical website, but I'm also not a lawyer, or a specialist in data privacy for that matter. Still, if my business relied largely on storing personal data, I would probably consider taking every precaution in order to avoid a full-blown disaster ?
    1 point
  45. Just a note, to give WireMailSmtp a third party access on your Gmail account, you have to enable "Less Secure Apps". https://support.google.com/accounts/answer/6010255 Thanks for this tutorial ?
    1 point
  46. OMGOODNESSS! Yesterday I was on XAMPP, earlier today I was on WAMP SERVER ... as of 20 minutes ago I am now on LARAGON - and it is superbly amazing! My favorite feature is the easy at setting up VirtualHosts and the email server? Literally took seconds! THANK YOU ROBIN!
    1 point
  47. Some fresh sounds I discovered recently. I didn't know I'd like this Synthwave music but... can't get anything done without it. Whole YT Channel: https://www.youtube.com/channel/UCmYTgpKxd-QOJCPDrmaXuqQ Some more on Basecamp. If you loved Stranger Things (Netflix) you will probably like this too. https://synthwavecafe.bandcamp.com/album/stranger-things-tribute
    1 point
  48. They pick up the phone and call me. I have sent them the admin account details but I' sure they have never been there ? (not just this one but many others) Of course if they would REALLY like to edit their site I could not use an SSG. Often the case is that they do like the idea to be able to manage the content. But when the time comes they realize it's work and it would require effort.
    1 point
  49. Hi @netcarver - thanks for your thoughts. Nico has just given me push permissions to the repo for this module so I could now start maintaining this module moving forward. However, I honestly don't really want another high profile module on my list of things to support at the moment, so if I do take this on, I will be looking for the community to help with PRs moving forward. Regarding your suggestion to me via PM about a community Github organization - I still think this might be a good idea, but I am also ok with being the gatekeeper for the module, just not wanting to take on being the support person - does that make sense? The other issue is that my fork has several breaking changes that prevent easy upgrading from the current master version that is in the modules directory, so without some manual DB changes, it should only be used for new installs. Anyone else have any thoughts on how best to proceed to ensure no-one breaks there site when upgrading to my new version? Maybe I just need to add an upgrade() method that prevents the module from updating old installs?
    1 point
  50. You can sort them in a saveReady hook. In /site/ready.php: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // If the page has the relevant template... if($page->template == 'exhibition') { // Sort the Page Reference field by title $page->works_id->sort('title') ; } }); This of course prevents you from applying a manual sort to the field, and does affect the sort order of the field value when you get it in your template. But it sounds like you are specifying a different sort (chronological) there anyway so that won't be an issue.
    1 point
×
×
  • Create New...