Leaderboard
Popular Content
Showing content with the highest reputation on 07/20/2014 in all areas
-
Hi everyone, Here's a little module that allows you to force users to change their password on their first login, or at any time if you manually force it. http://modules.processwire.com/modules/password-force-change/ https://github.com/adrianbj/PasswordForceChange Key Features During install it creates a new checkbox field in the user template, "force_passwd_change". Automatic checking of this checkbox when creating a new user is determined by the "Automatic Force Change" module config setting. When a user logs in for the first time (or if you have manually checked that field for an existing user), they will be warned that they have to change their password and they'll be automatically redirected to their profile page. They must change their password to something new - they are not allowed to re-enter their existing password. Bulk "Set All Users" option to at any time, force all users (by selected roles) to change their password. Hopefully some of you will find it useful and please let me know if you have any suggested changes/enhancements. PS I used the new info.json way of defining the module details, so it requires PW 2.4.3+7 points
-
Hi there, remember my Knowledge Base Site Profile? In there, I implemented a simple "internal bookmarking system", but hard-wired it into the templates then. In order to start rewriting this mentioned profile I made a module out of this page flagging thingy: https://github.com/marcus-herrmann/FlagPages/ With this module, a logged in user can flag/unflag pages, on whose template the flag link (see below) has been placed. These flags serve as "personal bookmarks" and are not a site-wide sticky setting. It's a proof of concept and not heavily tested, still! So please use with caution. Usage On the module's config page you can set the user roles allowed to flag pages. Per default this ability is restricted to "superuser". If you are adding further roles, please seperate the entries with whitespace: superuser editor foorule On the markup side, FlagPages module consists of two parts: Rendering the link and rendering a list with your current bookmarks. First of all, load the module via: $flag = $modules->get("FlagPages"); Rendering flag toggle linkThen, use the renderLink method and place the output in your template. By adding the link to all or just certain templates, you can control which templates can be flagged and which can't. echo $flag->renderLink(); The default output will be "Add {Name} to flags", or "Remove {Name} from flags". You can override these labels with parameters. For example: echo $flag->renderLink("Add %s to my bookmarks", "Remove %s from my bookmarks"); Rendering the flagged pages list echo $flags->renderList(); This will output a simple unordered list with links to pages the currently logged-in user has set a flag to. Installation Requirement: ProcessWire 2.4 (although I haven't tested it in older versions, frankly) Manually Download or git clone, rename the module folder to "FlagPages" and put it into your site/modules folder Go to modules overview page and click "Check for new modules" Install the module. The module will appear under "Flag" section. Download here Have fun! edit: Simplified renderLink param logic according to teppo's advice5 points
-
I needed all but one template on a site to render https. I had a lot of templates on the site in question so it was easiest to change them all to be https like this at the very top of head.inc: foreach ($templates as $template) { $template->https = 1; $template->save(); } Then I loaded a page on the site once, removed the code and changed the one template I DIDN'T want to be https to force http instead (of course you could add a check in the code above for that template, but it was as quick either way!). It was a rare occasion where a site had about 25 templates and I needed to first make this change on dev, then live, so this was far quicker than ticking them all apart from one to https manually. Hope it's of use to someone. The value for forcing non-https is -1 and the default (allow both) is 0 by the way.5 points
-
Hey guys! I was having some trouble with the RTEs adding the height attribute to images, because it was distorting all my images (I'm using max-width on the CSS), and decided to do something about it. So, here's a small Textformatter module that removes all the Height attributes from RTE fields where it's activated. https://github.com/ocorreiododiogo/PW-removeHeights4 points
-
Thanks Can, good luck with your project The new version is now merged into the master branch, I also updated the README on GitHub. With v.1.1.1, a new config option was introduced: Creation mode This setting controls when the PDF files are generated and stored for caching purposes. The default value is still "on click", right before downloading a PDF file. Now, the PDF files can also be created when saving pages in the ProcessWire admin. This new option is preferable if the PDFs are heavy and need some time for processing - the clients won't have to wait for it. Please post any problems or questions regarding updating the module to the new version in this thread.4 points
-
Hi Gerhard, If you grab the latest version of the module (1.1.0 is now in the master) you have several possibilites to solve this. 1) Use pages2pdf module: Do you already have a template that shows/lists the pages inside the shopping cart for a user? If so, you could create a corresponding template in /site/templates/pages2pdf/ and list the products there too. This way, the module does most of the work for you, including caching of the PDF files. What you'd need here is to delete the cached PDF file if the user adds or removes a page in the shopping cart. Simplest way of doing this is to trigger saving the shopping cart page, then the module will delete the cached PDF file. 2) Use WirePDF module: WirePDF is just wrapper around mPDF that is optimized to work with ProcessWire. If you want to create the PDF files independently from Pages2Pdf module, you may want to check out those examples: https://github.com/wanze/Pages2Pdf#wirepdf2 points
-
Dude! I've always wanted to do on-the-fly PDF brochures of some pages on a site I have, but have always put it off as thinking I don't have enough spare time to justify it, and don;t really want to fight stupid PDF libraries to get a decent result.. Well, after reading your tut I decided it looked easier than I have previously thought. In about 2 hours this morning I've nailed this with some outstanding results, sooo easy! I thought there would be issues getting PDF data to display right etc (these things are never straight-forward) but no, mpdf is the bomb! So thanks for the enticing post that got me going with this, and guys, if you like me think PDF generation will be more trouble than it's worth, I encourage you to give it a go.2 points
-
--------------------------------------------------------------------------------------------------------------------------------- when working with PW version 2.6+, please use Pim2, not Pim! read more here on how to change from the older to the newer version in existing sites --------------------------------------------------------------------------------------------------------------------------------- PageImage Manipulator, API for version 1 & 2 The Page Image Manipulator is a module that let you in a first place do ImageManipulations with your PageImages. - And in a second place there is the possibility to let it work on any imagefile that exists in your servers filesystem, regardless if it is a 'known PW-image'. The Page Image Manipulator is a Toolbox for Users and Moduledevelopers. It is written to be as close to the Core ImageSizer as possible. Besides the GD-filterfunctions it contains resize, crop, canvas, rotate, flip, sharpen, unsharpMask and 3 watermark methods. How does it work? You can enter the ImageManipulator by calling the method pim2Load(). After that you can chain together how many actions in what ever order you like. If your manipulation is finished, you call pimSave() to write the memory Image into a diskfile. pimSave() returns the PageImage-Object of the new written file so we are able to further use any known PW-image property or method. This way it integrates best into the ProcessWire flow. The three examples above put out the same visual result: a grayscale image with a width of 240px. Only the filenames will slightly differ. You have to define a name-prefix that you pass with the pimLoad() method. If the file with that prefix already exists, all operations are skipped and only the desired PageImage-Object gets returned by pimSave(). If you want to force recreation of the file, you can pass as second param a boolean true: pim2Load('myPrefix', true). You may also want to get rid of all variations at once? Than you can call $pageimage->pim2Load('myPrefix')->removePimVariations()! A complete list of all methods and actions are at the end of this post. You may also visit the post with tips & examples for users and module developers. How to Install Download the module Place the module files in /site/modules/PageImageManipulator/ In your admin, click Modules > Check for new modules Click "install" for PageImageManipulator Done! There are no configuration settings needed, just install and use it. Download (version 0.2.0) get it from the Modules Directory History of origins http://processwire.com/talk/topic/3278-core-imagemanipulation/ ---------------------------------------------------------------------------------------------------------- Page Image Manipulator - Methods * pimLoad or pim2Load, depends on the version you use! pimLoad($prefix, $param2=optional, $param3=optional) param 1: $prefix - (string) = mandatory! param 2: mixed, $forceRecreation or $options param 3: mixed, $forceRecreation or $options return: pim - (class handle) $options - (array) default is empty, see the next method for a list of valid options! $forceRecreation - (bool) default is false It check if the desired image variation exists, if not or if forceRecreation is set to true, it prepares all settings to get ready for image manipulation ------------------------------------------------------------------- * setOptions setOptions(array $options) param: $options - (array) default is empty return: pim - (class handle) Takes an array with any number valid options / properties and set them by replacing the class-defaults and / or the global config defaults optionally set in the site/config.php under imageSizerOptions or imageManipulatorOptions. valid options are: quality = 1 - 100 (integer) upscaling = true | false (boolean) cropping = true | false (boolean) autoRotation =true | false (boolean) sharpening = 'none' | 'soft' | 'medium' | 'strong' (string) bgcolor = (array) css rgb or css rgba, first three values are integer 0-255 and optional 4 value is float 0-1, - default is array(255,255,255,0) thumbnailColorizeCustom = (array) rgb with values for colorize, integer -255 - 255 (this can be used to set a custom color when working together with Thumbnails-Module) outputFormat = 'gif' | 'jpg' | 'png' (Attention: outputFormat cannot be specified as global option in $config->imageManipulatorOptions!) set {singleOption} ($value) For every valid option there is also a single method that you can call, like setQuality(90), setUpscaling(false), etc. ------------------------------------------------------------------- * pimSave pimSave() return: PageImage-Object If a new image is hold in memory, it saves the current content into a diskfile, according to the settings of filename, imagetype, targetFilename and outputFormat. Returns a PageImage-Object! ------------------------------------------------------------------- * release release() return: void (nothing) if you, for what ever reason, first load image into memory but than do not save it, you should call release() to do the dishes! ? If you use pimSave() to leave the ImageManipulator, release() is called automatically. ------------------------------------------------------------------- * getOptions getOptions() return: associative array with all final option values example: ["autoRotation"] bool(true) ["upscaling"] bool(false) ["cropping"] bool(true) ["quality"] int(90) ["sharpening"] string(6) "medium" ["targetFilename"] string(96) "/htdocs/site/assets/files/1124/pim_prefix_filename.jpg" ["outputFormat"] string(3) "jpg" get {singleOption} () For every valid option there is also a single method that you can call, like getQuality(), getUpscaling(), etc. See method setOptions for a list of valid options! ------------------------------------------------------------------- * getImageInfo getImageInfo() return: associative array with useful informations of source imagefile example: ["type"] string(3) "jpg" ["imageType"] int(2) ["mimetype"] string(10) "image/jpeg" ["width"] int(500) ["height"] int(331) ["landscape"] bool(true) ["ratio"] float(1.5105740181269) ["bits"] int(8) ["channels"] int(3) ["colspace"] string(9) "DeviceRGB" ------------------------------------------------------------------- * getPimVariations getPimVariations() return: array of Pageimages Collect all pimVariations of this Pageimage as a Pageimages array of Pageimage objects. All variations created by the core ImageSizer are not included in the collection. ------------------------------------------------------------------- * removePimVariations removePimVariations() return: pim - (class handle) Removes all image variations that was created using the PIM, all variations that are created by the core ImageSizer are left untouched! ------------------------------------------------------------------- * width width($dst_width, $sharpen_mode=null) param: $dst_width - (integer) param: $auto_sharpen - (boolean) default is true was deleted with version 0.0.8, - sorry for breaking compatibility param: $sharpen_mode - (string) possible: 'none' | 'soft' | 'medium' | 'strong', default is 'soft' return: pim - (class handle) Is a call to resize where you prioritize the width, like with pageimage. Additionally, after resizing, an automatic sharpening can be done with one of the three modes. ------------------------------------------------------------------- * height height($dst_height, $sharpen_mode=null) param: $dst_height - (integer) param: $auto_sharpen - (boolean) default is true was deleted with version 0.0.8, - sorry for breaking compatibility param: $sharpen_mode - (string) possible: 'none' | 'soft' | 'medium' | 'strong', default is 'soft' return: pim - (class handle) Is a call to resize where you prioritize the height, like with pageimage. Additionally, after resizing, an automatic sharpening can be done with one of the three modes. ------------------------------------------------------------------- * resize resize($dst_width=0, $dst_height=0, $sharpen_mode=null) param: $dst_width - (integer) default is 0 param: $dst_height - (integer) default is 0 param: $auto_sharpen - (boolean) default is true was deleted with version 0.0.8, - sorry for breaking compatibility param: $sharpen_mode - (string) possible: 'none' | 'soft' | 'medium' | 'strong', default is 'soft' return: pim - (class handle) Is a call to resize where you have to set width and / or height, like with pageimage size(). Additionally, after resizing, an automatic sharpening can be done with one of the three modes. ------------------------------------------------------------------- * stepResize stepResize($dst_width=0, $dst_height=0) param: $dst_width - (integer) default is 0 param: $dst_height - (integer) default is 0 return: pim - (class handle) this performs a resizing but with multiple little steps, each step followed by a soft sharpening. That way you can get better result of sharpened images. ------------------------------------------------------------------- * sharpen sharpen($mode='soft') param: $mode - (string) possible values 'none' | 'soft'| 'medium'| 'strong' return: pim - (class handle) Applys sharpening to the current memory image. You can call it with one of the three predefined pattern, or you can pass an array with your own pattern. ------------------------------------------------------------------- * unsharpMask unsharpMask($amount, $radius, $threshold) param: $amount - (integer) 0 - 500, default is 100 param: $radius - (float) 0.1 - 50, default is 0.5 param: $threshold - (integer) 0 - 255, default is 3 return: pim - (class handle) Applys sharpening to the current memory image like the equal named filter in photoshop. Credit for the used unsharp mask algorithm goes to Torstein Hønsi who has created the function back in 2003. ------------------------------------------------------------------- * smooth smooth($level=127) param: $level - (integer) 1 - 255, default is 127 return: pim - (class handle) Smooth is the opposite of sharpen. You can define how strong it should be applied, 1 is low and 255 is strong. ------------------------------------------------------------------- * blur blur() return: pim - (class handle) Blur is like smooth, but cannot called with a value. It seems to be similar like a result of smooth with a value greater than 200. ------------------------------------------------------------------- * crop crop($pos_x, $pos_y, $width, $height) param: $pos_x - (integer) start position left param: $pos_y - (integer) start position top param: $width - (integer) horizontal length of desired image part param: $height - (integer) vertical length of desired image part return: pim - (class handle) This method cut out a part of the memory image. ------------------------------------------------------------------- * canvas canvas($width, $height, $bgcolor, $position, $padding) param: $width = mixed, associative array with options or integer, - mandatory! param: $height = integer, - mandatory if $width is integer! param: $bgcolor = array with rgb or rgba, - default is array(255, 255, 255, 0) param: $position = one out of north, northwest, center, etc, - default is center param: $padding = integer as percent of canvas length, - default is 0 return: pim - (class handle) This method creates a canvas according to the given width and height and position the memory image onto it. You can pass an associative options array as the first and only param. With it you have to set width and height and optionally any other valid param. Or you have to set at least width and height as integers. Hint: If you want use transparency with rgba and your sourceImage isn't of type PNG, you have to define 'png' as outputFormat with your initially options array or, for example, like this: $image->pimLoad('prefix')->setOutputFormat('png')->canvas(300, 300, array(210,233,238,0.5), 'c', 5)->pimSave() ------------------------------------------------------------------- * flip flip($vertical=false) param: $vertical - (boolean) default is false return: pim - (class handle) This flips the image horizontal by default. (mirroring) If the boolean param is set to true, it flips the image vertical instead. ------------------------------------------------------------------- * rotate rotate($degree, $backgroundColor=127) param: $degree - (integer) valid is -360 0 360 param: $backgroundColor - (integer) valid is 0 - 255, default is 127 return: pim - (class handle) This rotates the image. Positive values for degree rotates clockwise, negative values counter clockwise. If you use other values than 90, 180, 270, the additional space gets filled with the defined background color. ------------------------------------------------------------------- * brightness brightness($level) param: $level - (integer) -255 0 255 return: pim - (class handle) You can adjust brightness by defining a value between -255 and +255. Zero lets it unchanged, negative values results in darker images and positive values in lighter images. ------------------------------------------------------------------- * contrast contrast($level) param: $level - (integer) -255 0 255 return: pim - (class handle) You can adjust contrast by defining a value between -255 and +255. Zero lets it unchanged, negative values results in lesser contrast and positive values in higher contrast. ------------------------------------------------------------------- * grayscale grayscale() return: pim - (class handle) Turns an image into grayscale. Remove all colors. ------------------------------------------------------------------- * sepia sepia() return: pim - (class handle) Turns the memory image into a colorized grayscale image with a predefined rgb-color that is known as "sepia". ------------------------------------------------------------------- * colorize colorize($anyColor) param: $anyColor - (array) like css rgb or css rgba - but with values for rgb -255 - +255, - value for alpha is float 0 - 1, 0 = transparent 1 = opaque return: pim - (class handle) Here you can adjust each of the RGB colors and optionally the alpha channel. Zero lets the channel unchanged whereas negative values results in lesser / darker parts of that channel and higher values in stronger saturisation of that channel. ------------------------------------------------------------------- * negate negate() return: pim - (class handle) Turns an image into a "negative". ------------------------------------------------------------------- * pixelate pixelate($blockSize=3) param: $blockSize - (integer) 1 - ??, default is 3 return: pim - (class handle) This apply the well known PixelLook to the memory image. It is stronger with higher values for blockSize. ------------------------------------------------------------------- * emboss emboss() return: pim - (class handle) This apply the emboss effect to the memory image. ------------------------------------------------------------------- * edgedetect edgedetect() return: pim - (class handle) This apply the edge-detect effect to the memory image. ------------------------------------------------------------------- * getMemoryImage getMemoryImage() return: memoryimage - (GD-Resource) If you want apply something that isn't available with that class, you simply can check out the current memory image and apply your image - voodoo - stuff ------------------------------------------------------------------- * setMemoryImage setMemoryImage($memoryImage) param: $memoryImage - (GD-Resource) return: pim - (class handle) If you are ready with your own image stuff, you can check in the memory image for further use with the class. ------------------------------------------------------------------- * watermarkLogo watermarkLogo($pngAlphaImage, $position='center', $padding=2) param: $pngAlphaImage - mixed [systemfilepath or PageImageObject] to/from a PNG with transparency param: $position - (string) is one out of: N, E, S, W, C, NE, SE, SW, NW, - or: north, east, south, west, center, northeast, southeast, southwest, northwest default is 'center' param: $padding - (integer) 0 - 25, default is 5, padding to the borders in percent of the images length! return: pim - (class handle) You can pass a transparent image with its filename or as a PageImage to the method. If the watermark is bigger than the destination-image, it gets shrinked to fit into the targetimage. If it is a small watermark image you can define the position of it: NW - N - NE | | | W - C - E | | | SW - S - SE The easiest and best way I have discovered to apply a big transparency watermark to an image is as follows: create a square transparent png image of e.g. 2000 x 2000 px, place your mark into the center with enough (percent) of space to the borders. You can see an example here! The $pngAlphaImage get centered and shrinked to fit into the memory image. No hassle with what width and / or height should I use?, how many space for the borders?, etc. ------------------------------------------------------------------- * watermarkLogoTiled watermarkLogoTiled($pngAlphaImage) param: $pngAlphaImage - mixed [systemfilepath or PageImageObject] to/from a PNG with transparency return: pim - (class handle) Here you have to pass a tile png with transparency (e.g. something between 150-300 px?) to your bigger images. It got repeated all over the memory image starting at the top left corner. ------------------------------------------------------------------- * watermarkText watermarkText($text, $size=10, $position='center', $padding=2, $opacity=50, $trueTypeFont=null) param: $text - (string) the text that you want to display on the image param: $size - (integer) 1 - 100, unit = points, good value seems to be around 10 to 15 param: $position - (string) is one out of: N, E, S, W, C, NE, SE, SW, NW, - or: north, east, south, west, center, northeast, southeast, southwest, northwest default is 'center' param: $padding - (integer) 0 - 25, default is 2, padding to the borders in percent of the images length! param: $opacity- (integer) 1 - 100, default is 50 param: $trueTypeFont - (string) systemfilepath to a TrueTypeFont, default is freesansbold.ttf (is GPL & comes with the module) return: pim - (class handle) Here you can display (dynamic) text with transparency over the memory image. You have to define your text, and optionally size, position, padding, opacity for it. And if you don't like the default font, freesansbold, you have to point to a TrueTypeFont-File of your choice. Please have a look to example output: http://processwire.com/talk/topic/4264-release-page-image-manipulator/page-2#entry41989 ------------------------------------------------------------------- PageImage Manipulator - Example Output1 point
-
I updated the module to version 1.0.1. All engines now have a setting Global template file where you can enter the filename of a template file that is used as "main template" behind the API variable. This is useful if you have a main template that contains all the markup and you need to fill certain variables per controller. Note that Smarty and Twig already support this feature with template inheritance. Also the TemplateEngineProcesswire module now supports custom suffixes for the template files. Change this setting if you'd like to name the templates different than the controller, e.g "home.tpl.php". Cheers1 point
-
Hey guys, got asked to share how to set up mpdf with processwire so it's time to make a little tutorial Disclaimer: ( ) This is my first tutorial and I'm not a real coder yet so every tips and hints are highly appreciated Grab a copy of mPDF unzip it and put it in a nice place outside of your Processwire folder(s) - (as far as I remember is has to be outside or within a module to work, but I could be wrong?!) Open the template from which you want to create the PDF from In my case I have a "course.php" which is showing a page with a weekly schedule table and I wanted to provide this schedule as pdf next to the website version. I turned on urlSegments for "course" template, because I find it nicer than a get variable Then in my course.php template file after the normal website output I added the following It's probably better to have this logic at the very top of the template file to prevent unnecessary code execution right?? Aha, now I remember why it's at the bottom. I have some more logic above it which I wanted to share for browser output and pdf creation and this was the easiest way, probably I'll rearrange everything to make it faster At least the if( file_exists logic could go at the very top <?php // In case you don't have other urlSegments it's better to throw a 404 when someone types a non existing url, // could be managed better but at the moment it's easier if($input->urlSegment1 && $sanitizer->pageName($input->urlSegment1) != 'pdf') throw new Wire404Exception(); // if urlSegment /pdf/ output course table as PDF file if($sanitizer->pageName($input->urlSegment1) === 'pdf') { // $config->paths->files = PWs /assets/files/ folder, page ID and the title of the page could be any field or anything else // maybe you want to add the date $pdfPath = $config->paths->files . $page->id . "/" . $page->title.'.pdf'; // Options for wireSendFile because they're needed more then once $wireSendOptions = array('exit' => true, 'forceDownload' => true, 'downloadFilename' => ''); // If file already exists force download it and stop further execution which is handled $wireSendOptions 'exit' => true if(file_exists( $pdfPath )) wireSendFile($config->paths->files . $page->id . "/" . $headline.'.pdf', $wireSendOptions ); // include mPDF.php conditionally for localhost and productive website, you probably don't need it if structure is the same // included it at this point because we don't need it to provide an existing file // you could even include it after your output logic just before PDF creation.. if($config->httpHost == 'localhost') { include("../../../../classes/MPDF57/mpdf.php") } else { include("../../../classes/MPDF57/mpdf.php"); } // at this point you create the logic for your output // I'm not sure wether mPDF understands single 'quotes' properly // TCPDF doesn't really liked them so I stick to double "quotes" for now // just a little example how it might look you can of course have a loop populate everything from $page or somewhere else ;-) $pdfOutput = '<table class="data"> <tr> <th>Entry Header 1</th> <th>Entry Header 2</th> <th>Entry Header 3</th> <th>Entry Header 4</th> </tr> <tr> <td>Entry First Line 1</td> <td>Entry First Line 2</td> <td>Entry First Line 3</td> <td>Entry First Line 4</td> </tr> <tr> <td>Entry Line 1</td> <td>Entry Line 2</td> <td>Entry Line 3</td> <td>Entry Line 4</td> </tr> <tr> <td>Entry Last Line 1</td> <td>Entry Last Line 2</td> <td>Entry Last Line 3</td> <td>Entry Last Line 4</td> </tr> </table>'; // now the best part // the next comment explains the mPDF() parameters as in the manual http://mpdf1.com/manual/index.php?tid=184 // mode, format, default_font_size, default_font, margin_left, margin_right, // margin_top, margin_bottom, margin_header, margin_footer, orientation $mpdf = new mPDF('utf-8','A4-L', 0, '', 5, 5, 16, 6, 5, 5, 'L'); // The header is repeated on all pages, it's possibly to have different headers (even/odd) and other fancy stuff // You can have images as well, just have a look at the documentation it's pretty good $mpdf->SetHTMLHeader("<h2>{$page->title}</h2>"); // this one puts your table, created above, into the file $mpdf->WriteHTML($pdfOutput); // I'm saving the PDF file to the disc first as set in line 9 // 'D' would output the file inline in the browser window but then we're not able to store it for faster serving $mpdf->Output($pdfPath,'F'); // Thanks to Ryan and his nice functions we can use wireSendFile (as above) to get the created file and force download it wireSendFile($pdfPath, $wireSendOptions ); } // End if /pdf/ If you want to create the file everytime it's called and don't want the it to get stored just strip line 12, 15 and 67 and change the 'F' in line 64 to 'D' If you want to have a newly created file each time you change the page you have to install a little module to hookAfter page save It's just one file, I called it like hooks.module because maybe I will add some hooks later and there is no need to have each hook in a separate module. <?php class Hooks extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Custom Hooks', 'summary' => 'Hooks, PDF deletion on page save for example', 'version' => 1, 'autoload' => true, // You want it to autoload, otherwise it would never get called ); } public function init() { $this->pages->addHookAfter('save', $this, 'deletePDF'); //initialise the hook } // Most of it is just copied from Pages2PDF module from Wanze, a little 'simplified' though^^ public function deletePDF(HookEvent $event) { $page = $event->arguments[0]; $pdf = wire('config')->paths->files . $page->id . "/" . $page->title.'.pdf'; if (file_exists($pdf) && is_file($pdf)) { $name = $page->title.'.pdf'; if (@unlink($pdf)) { $this->message($this->_(sprintf("The following file got deleted '%s'", $name))); } else { $this->error($this->_(sprintf("Failed to delete '%s'", $name))); } } } } Hope you can follow the steps. Please let me know if not and why Any improvements are welcome because I would love to learn more as well1 point
-
1 point
-
TS already set that value if i read his post correctly1 point
-
My issue was related to wrong apache user/group in my vagrant box. After changing those I can now login.1 point
-
Finally was able to solve my issue. It was related to user/permissions on my vagrant box. apache was running as the wrong user. After changing that I can now login1 point
-
You don't need the if statement, as it doesn't matter on which page you are. The menuitems are in each case the same. <?php $alalehed = $pages->get("/andmebaas/"); $children = $alalehed->children; $children->prepend($alalehed); foreach($children as $child) { $class = $child === $page ? " active" : ''; echo "<li class='sidesub$class'><a href='{$child->url}'>{$child->title}</a></li>"; } ?>1 point
-
Check site/config.php - there is an entry for timezone about line ~24: $config->timezone = 'Europe/London';1 point
-
The easiest way would be to hardcode the parents id. There's no real way around some form of hardcoding, as from some source the code has to know, which site should be your root page. If you want the menu to remain slightly more dynamic you could use a page-field, where you could change the parent page from the backend. If your mentioned parent page also is the homepage, then you could use this to get the page: $parent = $pages->get("/"); This always selects the root of the processwire pagetree.1 point
-
This site is very, very good with nice design. I saw that you integrated and segment.io service, content is compressed, response fast etc... Congratulations!1 point
-
Was thinking about the possible implementations of this outside your KB site profile... Could it be used in online-stores for something like "wishlist" or "to see later"?1 point
-
Looks great Marcus, I'm looking forward to trying this out! Just thinking out loud, but you could, perhaps, simplify this a bit without sacrificing any flexibility: // the sprintf way echo $flags->renderLink("Add %s to flags", "Remove %s from flags"); // the placeholder way echo $flags->renderLink("Add {flag} to flags", "Remove {flag} from flags");1 point
-
I'm still not sure exactly which way to go with PDF creation. There is also a client side JS library: https://github.com/MrRio/jsPDF We'll have to check this out more thoroughly. Maybe it will make things like floating images possible?1 point
-
Hi @leoric, I assume the error occures on the imagefield named watermark as you can use the pimLoad method with the field named images. Here are a few questions: Does your template / page have an imagefield with (exactly) that name? Is this imagefield set to accept only a single image?1 point
-
I went ahead and removed the affiliate links and altered the first one to a regular link to the digitalocean homepage. Sorry @goro2, I would prefer to be welcoming you for the first post, but nothing on it tells us that you will stick around in the forum after dropping the link here.1 point
-
I don't know what our guidelines are about affiliate links, but I think it would be cool at least always mention when using affiliate links. Referring to above post.1 point
-
Well redirects only working for "real" urls like "yoursite.com/home.html". Not for IDs in queries (the part behind "?"). What you could do is to add a switch to your index page (probably home.php in the templates folder): <?php switch($input->get->pid) { case '1': $session->redirect('http://thenewpage.com/newpath/'); // this will happen if pid in URL is 1 break; case '8': $session->redirect('http://thenewpage.com/anotherpath/'); // this will happen if pid in URL is 8 break; }1 point
-
multi-value fields -> implode / explode comma separated values... Should be an easy way to do it1 point
-
My first post here, coming from mainly Wordpress. The holy grail for me is exactly the description below: That's really it, isn't it? For years I've been stuck between the lightweight PHP framework (like Codeigniter) versus full-on CMS (like Wordpress) thing. The former requires a lot of monotonous coding to get an api + admin set up, and the the latter gets you bogged down in superfluous features.1 point
-
Think you could make your own little "cart" just a littly form with a hidden field for storing the page->id or if this form is on the same page you want to add to the cart you don't even need the hidden field. if($input->post->addtocart && !$cart) { $cart = new Page(); $cart->parent = $pages->get(5771); $cart->template = 'cart'; $cart->title = 'session_id()'; //for example $cart->save(); $cart->of(false); $cart->items = $pages->id; //not a hundred percent sure right now but should work (think I've done it like this already) } } items field would be multi page fieldtype you would then include this "$modules->get('Pages2Pdf')->render();" into the page template you want to generate the pdf's from on the cart page you add a link for the customer, think it should work when you just link to one of the pages and append ?pdf=1 to the url, which will then create the pdf create a new template under /templates/pages2pdf/ with the same name as the template you put the "$modules->get('Pages2Pdf')->render();" in in this template you iterate through the pages in the cart like you would on a blog page or similar and output everything you need for me the final output worked only with heredoc syntax, seems that proper double quotes are needed by tcpdf (you could echo as "normal" but then you would need to escape the double quotes) hoffe es ist einigermaßen verständlich und klappt (hope it's understandable and works)1 point
-
Thanks Can for your ideas. After browsing through available modules, I think I'm going to use a modified version of Apeisa's cart module https://github.com/apeisa/Shop-for-ProcessWire/blob/master/ShoppingCart.module to add pages to a cart. Do you have any idea how to hook into the pages2pdf module on save/update of pages in the admin? I found this post https://processwire.com/talk/topic/2331-doing-additional-logic-after-saving-a-new-page/ Not sure though if that goes in the right direction and how to hook into pdf creation from there. Cheers Gerhard1 point
-
Yes, you can upload the same image as many times as you want Srly now, you can't use an already uploaded image from a field because images have a 1/1 relation with pages. This makes the system behave in a simpler and safer way, and there is not the risk of making images that are being used by a page from disappearing when their original page is deleted for some reason. If you need the same image in two different pages, the best bet is to re-upload it, and have two copies in the system. You can always reuse images from the templates by calling the page where they are in. This was discussed already some times but I don't have the time to search right now. You might want to search a bit in the forum to find some interesting discussions on this subject.1 point
-
Table Use this for tabular data, like rate tables or other things that you might typically represent in a spreadsheet. Use it for situations where you don't need the full-blown flexibility of repeaters, as it's technically more efficient with far less overhead than repeaters. Something like the Events Fieldtype could be very easily re-created via a Table field, but the potential uses are far broader. But for the most part, think tabular data when it comes to the Table field. Multipliers This is good for when you need a range of values (whether text, textarea, numbers, dates, etc.). If you are using repeaters with just one field in them, you might be a lot better off with a Multiplier. Like the Table field, Multipliers are very efficient and low overhead relative to something like Repeaters. Use Multipliers when you need to repeat a single input multiple times, optionally with a min and max number of inputs. Lets say you are building an employee directory, and each employee has between 1 and 3 email addresses. Rather than using 3 separate email fields, you would use 1 multiplier field and specify min=1 and max=3. Repeaters These are infinitely flexible in terms of what they represent, but each row of values is technically a page in the system. As a result, with the flexibility comes significant overhead. This is really only an issue when the quantity of repeater items gets high, or when you have lots (thousands) of pages using repeaters. I recommend repeaters for setting up things like homepage carousels. For example, if you go to the Villas of Distinction homepage, there are 3 separate repeaters in use on that page, each holding a photo, title, description, link. The client can have as many items in each of those sections as they want. Currently it looks like the first repeater as 6 items, the 2nd has 2, and the 3rd has 6. The possibilities of what can be represented with repeaters is endless, but look for potential alternatives when dealing with large quantities (whether large quantities of repeater items, or large quantities of pages using repeaters). PageTable This is one of the ProFields that is available for free (thanks to Avoine sponsorship) on the ProcessWire dev branch. Meaning, it'll be available for everyone to use as part of the core in ProcessWire 2.5. And you can use it now if you don't mind running the dev branch. PageTable has all the flexibility of repeaters, but with lower overhead from the admin/input perspective. Rather than trying to bundle all the inputs on one screen, PageTable shows you a table of items and you click on the item to edit it in a modal window. This enables it to be a lot more efficient from the admin UI perspective. It's also more flexible than repeaters are in terms of where you store your items. PageTable lets you choose where they should live, whether as children of the page being edited, or as children of some other parent page you designate. They might be a little more work to setup than repeaters, but I think that most situations where you need the flexibility of repeaters may be better served by PageTable. PageTable still can't compete with the speed and efficiency of Table or Multiplier, but consider using PageTable anywhere that you might have used Repeaters before. Repeaters and PageTable are fundamentally different from the admin UI/input perspective, so you'd want to compare them yourself to see what suits your individual input needs better. PageTable involves more clicking to create and edit items, making Repeaters potentially faster for entering data rapidly. But PageTable will scale much further in the admin UI than Repeaters will, so I would personally favor PageTable in more situations than Repeaters.1 point
-
Hey Ryan! That saved my day, thx! I got the same 500 on a server of german hoster 1und1 - if any other "Kraut" has the same "bratwurst" problem.1 point
-
1 point
-
1 point
-
1 point
-
Ryan, I'm really impressed, amazed at your level of productivity, responsiveness (and generosity)!1 point
-
Here you go: http://modules.processwire.com/modules/fieldtype-text-unique/1 point
-
1 point
-
Hello to all of you, I'm new to Processwire and I've been trying desperately for a few hours to just... install it on my localhost (Ubuntu 12.04, Apache 2.2.22). You'll soon find out that I am not a professionel web developper, but still... this is driving me crazy and I'd love to get some help. To describe my problem briefly : installation goes fine, no problem. I set everything as asked during the process (writable directories and so on). Then I go to 'View my site' : just fine. And as soon as I hit ANY link on the Basic homepage, I get that 404 error quite a few talked about in other posts... So far, I've tested : - nonsens string in my .htaccess : throws a 500 error (sound good, no?) - re-read everything in my Apache setting (again I'm no professional and couldn't find anything wrong...) - checked the mod_rewrite in my phpinfo... Looks good. I'll put it underneath for those interested to help. - tried to uncomment the rewriteBase rule in the .htaccess. Nothing worked (actually, and that's CRAZY to me, it worked once on a reload (I DID see the ABOUT page simply putting for the nth time RewriteBase /mysubdir/, but it worked ONCE (can you believe this?) and never again. - tried restarting my Apache server many times... no change.... I can't think of anything else to do, so please, if someone can help, I'd greatly appreciate... Thanks in advance for your help and time. My phpinfo is attached.phpinfo.php.html Celfred. EDIT : Oh I'm SO sorry and ashamed... (Did I tell you I was no professional?) I had just one last idea before going to bed... trying one last change on my rewriteBase line and... It worked ! It's cool, but I can't believe it took me hours to find this out. Actually my server is installation is in private/processwire/ subfolder and I simply forgot the 'private' part in the path... I guess you can ignore my post now... Have a good night...1 point