Leaderboard
Popular Content
Showing content with the highest reputation on 10/17/2016 in all areas
-
I've had the go-ahead from @ESRCH and have now pushed this to the module repository. Repository Link7 points
-
The way I read the code in ProcessWire.php, this notice should only ever be triggered if you're bootstrapping PW and passing in a URL as the second parameter that contains a hostname not listed in $config->httpHosts. Is this generated by a bootstrap script? Which PW version do you use?4 points
-
4 points
-
<?php // only render output if there is something set in field json_ld_alternateName if(strlen($page->json_ld_alternateName) > 0) { echo " <script type='application/ld+json'> 'alternateName: '{$page->json_ld_alternateName}', </script>\n"; } I wrap "doublequotes" around the php string and use 'singlequotes' for strings within the markup. If you run into situations where you also would need doublequotes within the markup, you can use them if you escape them with a backslash: <?php echo "<p>A string with 'singlequotes' and escaped \"doublequotes\"!</p>"; // will output: <p>A string with 'singlequotes' and escaped "doublequotes"!</p>3 points
-
Hey everyone, Max from Snipcart here! We just published a full tutorial showing how to use ProcessWire + Snipcart (our dev-first HTML/JS shopping cart platform) to enable e-commerce. It was pretty much my first time playing around with the Apache/MySQL/PHP stack, so I'd love to get some feedback on the demo code. Oh, and also, if you feel like the Snipcart integration could have been done in a different/better way with ProcessWire, let me know! > Blog post tutorial > (Very) simple live demo > GitHub repo Cheers folks.2 points
-
Hi, After reading this thread, I decided to make a module that helps generating PDF files of ProcessWire pages. GitHub: https://github.com/wanze/Pages2Pdf Modules Directory: http://modules.processwire.com/modules/pages2-pdf/ This module uses the mPDF library to generate the PDF files. It has fully UTF-8 and basic HTML/CSS support for rendering the PDF files. The output is customizable with ProcessWire templates. Example I've enabled generating PDF files for the skyscraper template of ryans Skyscrapers-profile with a template that outputs the data in a table along with the body text and the images: one-atlantic-center-pdf-4177.pdf Please take a look at the README on GitHub for instructions and further information/examples. Cheers1 point
-
This is a very basic guide on how to optimize a ProcessWire page for speed. It doesn’t go into the depths of optimization and perfect render paths but will provide you with some proven ProcessWire methods for faster websites. The big problems that are easy to fix are what we aim for. You want quick improvements? Then read on… First let's have a look ath the following graph. Those are the areas, we want to improve. Source: http://httparchive.org/interesting.php?a=All&l=Oct%201%202014 Clean up your HTML Look at your HTML source code. Are there any unnecessary parts? Remove anything that might not be needed and try to keep your markup as clean as possible. Avoid using too many external JS libraries or other tools. It is okay to include jQuery from a CDN, because most visitors will already have cached the file. Too many of those external requests will slow down the page. If possible, try to avoid render-blocking Javascripts and move your script tags to the end of the page, right before the body. In most cases, your Javascript will enhance your content but doesn’t need to fire before the site is rendered. Always think if you need to include another library or the fourth webfont on your site. Minify Markup The next step to save some bytes is to remove all whitespaces from your markup. It doesn’t have to look nice, it has to be loaded fast. We perform this trick with our new super-weapon: The AllInOneMinify module for ProcessWire. Install it like every other module for ProcessWire. Once activated, go to the module settings and tick the checkbox for “Minify HTML” and look at your sites source code. It should be minified. AIOM can handle conditional browser comments. If your layout depends on whitespaces you could “force” them by putting an into the markup. Optimize the CSS Now we’re heading for the next larger part of a usual website. We will combine all CSS files and then remove anything not needed (whitespace,comments) from it. Before we start, make sure your CSS files only contain rules that you really use. Especially if you’re using a framework like Bootstrap, most of the selectors are never used. Remove them carefully. We need the AllIneOneMinify module from the previous step again. After installation, open the template file where your HTML header is generated. We will now replace all stylesheet tags with a single file. AIOM needs to know all CSS (or even LESS) files, relative to your template folder. It will then output a link to a single, compressed CSS file. You might have this in your HTML head: <link href="<? echo $config->urls->templates;?>/css/grid.css "rel="stylesheet" /> <link href="<? echo $config->urls->templates;?>/css/style.css“ rel="stylesheet" /> Replace all links to Stylesheets with the single tag like this: <link href=”<? echo AIOM::CSS(array(‘css/grid.css’,’css/style.css’)));?>” rel=”stylesheet”/> You pass an array with the file names to the AIOM method CSS. It will return a link to the file. AIOM takes care of image urls inside CSS. It will detect changes in the source file and only generate a new file if necessary. While developing, you might want to turn on the “Development” checkbox in the module settings. Make JavaScript tiny Do the same as you do to the CSS to your Javascript files. First, clean up the code. Then install AIOM and compress all JS files into a single file using the AIOM::JS method that works as the AIOM::CSS method. For best results, think about including scripts like jQuery from a CDN and put your scripts below the content, before you close the body tag. Also note that the order on how your throw your JS files into AIOM might be important, depending on the code inside. Get the right image size. ProcessWire comes with great image tools. Use them, to make images exactly the size you need them. You don’t have to serve that little thumbnail with over 3000px length just because the editor wasn’t able to reduce the size. Example: Your designer wants to have a slider image with a maximum size of 600x320 pixel. To output the image with that exact dimensions, use the API accordingly: $sliderImage->size(600,320)->url; An even better way would be to use adaptive images or the new srcset attribute combined with a JS fallback. Then your site only delivers the image size as needed. Hint: Play around with the image quality setting in the config.php. Maybe you don’t need images with a JPG quality of 90+. Compress the images further with minimize.pw To make images even smaller, we can use the minimize.pw service. This service will compress images nearly lossless by using more complicated tools to reduce the size of PNGs and JPEGs. By doing this, you remove bytes from the largest chunk of your website weight. minimize.pw is free for 2000 images. Just enter your E-Mailadress and receive a free key Then you have to install the ProcessImageMinimize module and enter they key. You can now activate the option to automatically compress every image uploaded. It is fail-safe and will compress images in the background. Please note, the automatic mode only works with images uploaded AFTER you have activated the module. You can manually select image fields with the ->mz() API method. Just include it before you output the image in your template file: $myImage->width(300,300)->mz()->url; We've closed the service. You could use something similar like Imgix ( https://www.imgix.com/ ). Activate GZip compression on your site Another method to speed up your site is to activate GZip compression. The server will then send all files compressed to the client. This works with nearly all browsers and the CPU power required is minimal. You can tell your server to do this, by adding those lines to your .htaccess file in your root directory. Please take care, that you do not overwrite the ProcessWire rules in the file! For best results add them on the top of the .htaccess file: <IfModule mod_deflate.c> AddOutputFilter DEFLATE js css AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html </IfModule> This was taken from another forum post. Tell the client to cache stuff To make repeating visits faster, we can tell the browser to cache special files for a longer period of time. Again, add this on top of your .htaccess file: <IfModule mod_expires.c> ExpiresActive On ExpiresDefault "access plus 1 seconds" ExpiresByType image/x-icon "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType text/css "access plus 1 month" ExpiresByType text/javascript "access plus 1 month" ExpiresByType application/octet-stream "access plus 1 month" ExpiresByType application/x-javascript "access plus 1 month" </IfModule> <IfModule mod_headers.c> <FilesMatch "\\.(ico|jpe?g|png|gif|swf|woff)$"> Header set Cache-Control "max-age=31536000, public" </FilesMatch> <FilesMatch "\\.(css)$"> Header set Cache-Control "max-age=2692000, public" </FilesMatch> <FilesMatch "\\.(js)$"> Header set Cache-Control "max-age=2692000, private" </FilesMatch> <FilesMatch "\.(js|css|xml|gz)$"> Header append Vary: Accept-Encoding </FilesMatch> Header unset ETag Header append Cache-Control "public" </IfModule> Remember, that this caching might be annoying while developing the site. Use the internal cache (or ProCache) Another trick to make the site faster is to use a caching system. This will “store” your rendered site so you don’t have to query the database that often. We can either do this with the internal cache of ProcessWire or use the commercial, official ProCache module. Using the build-in system, you go the the setting page of a template and open the “Cache” register. You can now set the Cache time and what happens if something changes. The settings depend on the content of the site. Mostly static content can be cached longer and you might not need to reset the cache every time. Dynamic sites will need shorter cache times. ProCache (buy here) is even faster because it will bypass PHP and the database. Files are served directly as HTML. Please note, that caching might make the site faster but it can create new problems. Use with care. Summary Keep your code as clean as possible. Remove anything unnecessary and then compress HTML,CSS and JS using the AIOM module. The largest part of your page weight are images. Keep them small by using the appropriate dimensions and consider services like minimize.pw. In the end, use intelligent caching and buy ProCache. Following this guide takes not more than an hour but can speed up your site and make your visitors happy. This was just a quick overview of techniques to optimize your page speed. There is plenty of stuff you can do but the steps above are a good first step. Maybe you can share your favorite methods (or links) to start the discussion.1 point
-
@kuba2 could you post the code but with: // template-name.php at the top of your snippets, it makes it a bit easier (for me personally) to tell what you are trying to do. For example: // product-index.php // I would guess this lists all your subpages of 'Products' // single-product.php // I would guess this is a single page showing the product (image/description/whatever) It's a small thing but it would help in your code above where you have: <?php foreach($page->image_field as $image) { // is 'image_field' the fieldname on a single product template? $thumbnail = $image->size(150,100); echo "<p><a href='{$image->url}'><img src='{$thumbnail->url}' alt='{$thumbnail->description}' ></a></p>"; } ?> and: <?php foreach ($page->children() as $product): ?> <div class='single-product-wrapper'> <img src="<?php echo $product->img->first()->url; // or is the image field called 'img'? ?> "/> <p><?php echo $product->inhalt1; ?></p> </div> <?php endforeach; ?> I'm a bit confused as to what you are doing and on what template. Seem to be getting there though! If you also want to set some defaults, you can have a look at this: https://processwire.com/docs/tutorials/how-to-structure-your-template-files/page4 The 'Adding an init.inc file to the mix (a best practice)' bit. Maybe you could set some image size defaults in there, I haven't tried this though (but probably will rather than have to set sizes all over the place).1 point
-
1 point
-
These subpages named home, etc, didn't they have a template called repeater_slider_repeater ? I'm not totally sure, but to a great extend, that the repeater items always have a template name with prefixed repeater_1 point
-
@jmartsch: I had this already in the back of my mind, but since PW doesn't enforce the precense of the mbstring extension in the installer, I want to tackle this problem with a viable fallback for non-mbstring systems. Assembling a failsafe wrapping solution without mbstring is a delicate subject though, so I want to give any code I propose a really thorough testing. I'm trying to get another pull request for WireMail out in the next few days. That patch will also have proper nesting of multipart types so that the HTML is rendered in all clients (especially Outlook) when attachments are present. Currently, some ignore the HTML in favor of the text part since all parts are treated equal in multipart-mixed.1 point
-
@BitPoet I found the solution for long subjects. Please use the function mb_encode_mimeheader for that. So line 435 in WireMail.php should read if (@mail($to, mb_encode_mimeheader($this->subject), $body, $header, $param)) $numSent++; Now the long subject is separated into multiple lines and each one is correctly wrapped with the correct code.1 point
-
@BitPoet´s fix for quoted-printable mails is merged into dev. I updated my WireMail class and tried sending an E-Mail with the new class. Now the HTML Part of the message with umlauts in it displays fine, but the title with german umlauts in it still does not display correct. I tried all sorts of conversions and adding headers to the mail but nothing worked. EDIT: This happens with multipart messages because they have no header like Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable But if I add those headers the rest of the mail is unreadable. How do I get correct umlauts in the title? Edit: I found the solution, attached it to the end of my post. Here is the some of the code I used: $betr = 'öäüß testmail' $mail = new \ProcessWire\WireMail(); // $mail->header('Content-Transfer-Encoding','base64'); // $mail->header('Content-Type', 'multipart/alternative; charset="utf-8"'); // $mail->header('charset', 'utf-8'); $mail->to('info@jensmartsch.de'); $mail->from('info@jensmartsch.de); $mail->fromName("Jens Martsch"); // $mail->subject(("$betr")); $mail->subject ('=?UTF-8?B?' . base64_encode($betr) . '?='); // $mail->subject(base64_encode('$betr')); // $mail->subject = "?utf-8?Q?" . quoted_printable_encode("öäüß The ï, ö, ë, ä, and é work, but when adding the ü it doesn't") . "?="; $mail->bodyHTML(($text)); if (!$mail->send()){ echo 'Fehler'; } This is the E-Mail header that I receive if I am using $mail->subject($betr); To: info@jensmartsch.de Subject: =?utf-8?Q?=C3=B6=C3=A4=C3=BC=C3=9F Bewerbung Berechnungsingenieur / Messtechniker Aut= omotive (m/w)?= X-PHP-Originating-Script: 0:WireMail.php From: =?utf-8?Q?Jens Martsch?= <info@jensmartsch.de> X-Mailer: ProcessWire/WireMail MIME-Version: 1.0 Content-Type: multipart/alternative; What I see as the title in my mail programm is exactly the same as the Subject SOLUTION: It seems that the length of my title was the problem. Now I try to find a solution for this as well. Maybe I just shorten the title.1 point
-
Hi, What is wrong with repeaters in your case? Can you please elaborate?1 point
-
Hi horst, thank you for your work on this modul. Is there a problem when I use it within a repeater? When I define an image-field like this: slider,1280,480,home_final the slider-croping-button don't appear on the page. If I define it without the template it works.1 point
-
1 point
-
1 point
-
First, Welcome to the ProcessWire Forum. I have moved this post (topic) to the "General Support" category. You mentioned in this topic that you liked a module. Could you please be more specific in which module are you asking about? I believe that will help someone to better assist you with your question. For your convenience, I have provided the link for ProcessWire Modules. http://modules.processwire.com/1 point
-
are you sure the value is blank? Mine works on the closed field, you just can't see the content until you click into the field; The field is still initialized when you open it; not sure if the fact that you can't see the content in the field is due to some initialization issue, or is something specific to how this component works. I'm not sure this can be fixed, so for now i think your options are to either tell the editors to click into the field to see the content, or don't use collapsed fields. In some future iteration of this module, the eventual aim is to have it operate more like CK editor, so that the config takes place from the admin, and each instance can be individually configured; also support for some sort of image input. But i think it will take a while till it reaches that stage, and also would depend on demand...1 point
-
If you go with a template for the major CMS you are pretty well stuck with slight modifications to your template. (if you start making major modifications you start to deal with update issues) If you want a website designed the way you want it you use Processwire as the design is separated from your CMS. We want a design first and then put in the CMS after we like the design. Opencart is my go to choice for eCommerce as I'm a PHP programmer and I can do anything I like with it given enough time and money. But it's an eCommerce package not heavy on the design and I find it a hassle to get it to give that flashy design - that costs time and that costs money. Plus a lot of template designers I have bought from don't update their designs regularily and Opencart has changed a lot between 1.6 and 2 and again between 2.0 and 2.2 so I'm a bit tired of changing templates with every major upgrade. For the price I'd rather keep Opencart for the eCommerce and get a designer to build me a nice flashy front end that I can then fill in with Processwire templates. I've yet to hit any major upgrade changes in Processwire that breaks the site I've had designed for it - not the case with most of my client's websites that have been designed to run on Wordpress, Joomla and Opencart. My clients seem to like personalised websites that stray from templates! I specifically don't want to reinvent the wheel of Opencart - I just want a flashier designed wheel for the front end of my client's site.1 point
-
Hi kongondo, Thanks for the quick reply and the welcome. I had actually already read the topic that you mention, and this is what prompted my need: I would like to save a "stock" field for each product, but this field would have to be calculated each time a stock movement is saved, and calculating this field is precisely what takes so much time. In the meantime, I continued looking into the problem, and I think that I came up with a solution with the following module: class PagesSum extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Pages Sum', 'version' => 1, 'summary' => 'Adds a $pages->sum($selectorString, $fieldName) function to sum the value of a specific field over a list of pages selected by a selector string.', 'singular' => true, 'autoload' => true ); } public function init() { $this->addHook('Pages::sum', $this, 'sum'); } public function sum($event) { $selectorString = $event->arguments(0); $fieldName = $event->arguments(1); // Find all the pages associated with the selector string $pageFinder = new PageFinder(); $idQuery = $pageFinder->findIDs(new Selectors($selectorString), array('returnQuery' => true)); $idQuery->set('orderby', array()); $idQuery->set('groupby', array()); $idQuery->set('limit', array()); $stmt = $idQuery->execute(); $idArray = $stmt->fetchAll(PDO::FETCH_COLUMN); // If no pages were found, return 0 if (count($idArray) == 0) { $event->return = 0; return; } $idString = implode(',', $idArray); // Get the table name for the given field name $field = $this->fields->get($fieldName); // If no field with this name is found, return 0; if (!$field) { $event->return = 0; return; } $tableName = $field->getTable(); // Run the SUM query $sumQuery = new DatabaseQuerySelect(); $sumQuery->select("SUM(data)"); $sumQuery->from($tableName); $sumQuery->where("pages_id IN ($idString)"); $stmt2 = $sumQuery->execute(); list($total) = $stmt2->fetch(PDO::FETCH_NUM); $event->return = $total; } } In my tests, it is about 60 times quicker to calculate the sum with the function $pages->sum($selectorString, $fieldName) than looping over the pages (for about 12000 pages). I would appreciate any feedback, in case there are any other optimizations to be achieved, or any errors I haven't thought about. And I hope that this might maybe be useful to others too!1 point