Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/20/2014 in all areas

  1. MarkupTagcloud The module generates a simple tagcloud based an page references as tags and a default template. Settings and template can be easily changed to fit your needs. Version 0.5.2Download Processwire module page: http://modules.processwire.com/modules/markup-tagcloud/ Bitbucket Repo: https://bitbucket.org/pwFoo/markuptagcloud/ Usage Readme fileExample output <ul> <li class="tag3"> <a class="tag3" href="/pw/tags/mytag/">myTag</a> </li> <li class="tag1"> <a class="tag1" href="/pw/tags/tag123/">tag123</a> </li> <li class="tag2"> <a class="tag2" href="/pw/tags/hello/">Hello</a> </li> <li class="tag2"> <a class="tag2" href="/pw/tags/tagged/">Tagged</a> </li> <li class="tag1"> <a class="tag1" href="/pw/tags/template/">Template</a> </li> <li class="tag1"> <a class="tag1" href="/pw/tags/template2/">Template2</a> </li> </ul> Tagcloud / list can be styled by css via weight / class.
    3 points
  2. Build my first PW website...., and not my last. Like PW a lot. It is fun to work with and sometimes a challenge. Spent, more than once, some ours fiddling on code issues, but real proud when I got it to work. Could not have done it without the feedback of the members from this community, thank you! Modules I used: -Email Obfuscation -Form Builder -SEO -Blog -Google Analytics -Protected Mode -Wire Mail SMTP Other: -Bootstrap -Animate -WOW -Unslider Website: http://www.tweemansterk.nl
    3 points
  3. Update 0.5.0: This version is not compatible with further releases (and still beta). https://github.com/NicoKnoll/MarkupSEO/blob/master/MarkupSEO.module I did a lot of changes and almost wrote the complete code new. Here are some main changes: Use normal fields instead of custom solution (this allows multilanguage and may prevents some compatibility problems) Added Twitter Cards Added an "Author" option Added a "title format" option (and a way to disable auto include of title) Rewrote most of fields descriptions Custom meta tags have to have a special format now + sanitizer for security (it's self explaining in the module itself) Fixed all issues You have to choose which templates should have a SEO tab instead of excluding now Let me hear what you think. And merry christmas
    3 points
  4. Hu guys I'm delighted to say that my new site is powered by Process Wire. Or rather, "Priceless Wine" and "Princess Wine" as my iPhone mistakenly predictive texts the name. There is also a page on ProcessWire in the CMS section which I'd love your feedback on. Currently I don't think it truly communicates PWs best features for Editors but it's a good start. Only almost finished? The site isn't 100% complete so consider this a "soft launch". Once complete, it'll replace my existing edenweb.ie site which wasn't being updated or developed as much as it should. - - - - - - - - - - - - - - - - - - - - - - - - - - - Background - Why ProcessWire pt 1. A few months back a key client who uses up approx 3 days of my week (for over 3 years) announced a pause on their web and marketing activities for various internal corporate reasons. This happened quite suddenly and obviously that left me with half my week "open" and needing to be filled. It also meant that I would be looking for new work and approaching prospects with a site which was approx 3 years out of date, under developed and didn't really communicate my latest skills or work. Not ideal! - I rapidly needed something live. But more importantly, I needed something better. I needed something built on a CMS which would allow me to rapidly publish content and accelerate future ideas and development. In short, my current CMS is/was great but I was tired of working around default field sets and presumptions it made about my content (amongst other reasons). With ProcessWire, the ability to have a page with just two fields (if I want) is remarkably underestimated. It means I can customise field layouts appropriate to my content. Even better - it means I can customise field layouts appropriate to my clients content and I choose my CMS on their requirements. Anyway, I made the decision to take a deep breath, take a few weeks to enjoy the extra unexpected free time and to rebuild the site in PW. My business will be 15 years old this January and I thought I'd mark the new year with a new domain, new business name and a new CMS. Here's to new beginnings! - - - - - - - - - - - - - - - - - - - - - - - - - - - Under the hood At the time of writing, the site is running 2.5.10 dev. There's not a huge amount of Modules running in the background. Where I've used a Module, it's been to accentuate back-end functionality rather than the front end. Config allows me to make setting changes directly within the admin. Its a great Module and saves me editing any config files and manually FTP'ing. Lister Pro gives me an easy way to manage the "studio updates". Hanna Code allows me to work with some of the tricker layouts such as the page on PW Forms is used for the Contact Form and I'm using direct embed with some jQuery and CSS to strip out some unwanted formatting. ProCache is running in the background to speed things up. Thats more out of professional curiosity right now Vs any focuseed attention on site speed. AIOM was running recentlyto minify all my style sheets and JS but I pulled it recently. might revisit. Blog module is running the er, blog! I've some work to do there in terms of content layout etc but it's a wonderful piece of work. RenoTheme is keeping everything lovely in the admin Upgrades is a real life saver and allows me to update the whole CMS in a few clicks MarkupSimpleNavigation is powering the menus. Regarding the actual PHP used in templates, I doubt there's anything there of interest to you seasoned PHP guys. I've achieved 99% of the site using simple foreach loops and PW selectors. - - - - - - - - - - - - - - - - - - - - - - - - - - - Background - Why ProcessWire pt 2. When I first heard of PW, I was very content with my current CMS so I had a brief look around the site, read some blog posts but ultimately moved on. It looked interesting but I didn't really have a need to investigate further. Fast forward a few years and realising I need to expand my CMS toolset a bit, I had a better look at PW and downloaded it. I really liked *some* elements and appreciated how I could determine the field layout. You see where this is going? Interest increasing! But honestly? I couldn't imagine putting my clients on front of PW with the theme it had (at the time) and TinyMCE as the default editor. It looked real clunky and I wasn't sure I wanted another CMS with the tree representing pages. Somewhat trivial and shallow reasons not to use something but there we go. I'm a designer and I also have to think about my clients experiences too. But I kept an eye on PW and in the background, a few things were happening which were interesting. Communication from Ryan was frequent, open and transparent Planned updates were being released on or before schedule Unplanned updates were often released on or before I realised I even needed them I discovered TinyMCE could be swappable for CK editor and I could use alternative admin themes I discovered a few Modules for listing pages via DataTables as opposed to tree mode Not really sure of the timeline here but this is from mid 2013 onwards btw. The crazy things is from that point onwards, it seemed increasingly impossible to ignore PW. Every few months there was an amazing leap in either the core features or some brilliant module I hoped for was published. EG: I was looking for a way to decrease the time it takes to publish a page in the right place with the right template and the Add New button appeared I was looking for a way to represent pages in a List rather than a tree and ListerPro was announed Hoping for a better way to upgrade PW and the Update module was released Needing a proper blog with categories and the Blog module was there Looking for a better admin UI and RenoTheme came along Needed more flexible field layouts in a matrix and ProFields released Looking for a way to store chunks of html/php etc and Hanna Code was released Ok, that sounds like an Arethra Franklin song about PW but you get the idea! Seriously, it got to the point where I was either silently (or via the Forums) hoping for a particular feature and Ryan would already be working on it or would just release it having finished it. And it was always done in a much more elegant, scalable and powerful way than I imagined or hoped. Just last month I wrote a forum post highlighting a wish for an admin-based settings module. Thinking "nah, there I go complicating things again. Make do with the config.php file" I deleted it. Literally the next day, the Config module was released. It's spooky! Anyway, I've rambled on a bit. But to sum up - I try to redo my site every few years in a different framework and platform. I can see the front-end framework changing in future but I think EdenStudios has found a good, permanent home in PW. PW and Ryan are doing everything right. It's not the only great CMS but it's a damn fine CMS in great hands supported by a great community.
    3 points
  5. In the admin we have an option to set a sorting for children using one field only. I have a problem with children getting sorted randomly when using a date field that is the same for multiple children. Usually we would sort by date and by ID or title, but we are only allowed to specify one field at a time. The problem with this is that once you edit one of those children, the sorting is randomly changed (actually everytime you edit a children) That's not really nice and very confusing. I had to use a dirty hook to change the children sorting one parent manually. $this->addHookBefore("ProcessPageList::find", $this, "sortingChildren"); public function sortingChildren(HookEvent $event){ $sel = $event->arguments("selectorString"); $page = $event->arguments("page"); if($page->template == "news-category"){ $event->setArgument("selectorString", $sel . ",sort=-datetime, sort=-id"); } } Maybe there's already a way I don't know or a module? But then I think this should be in core of course and not a module. Thanks.
    2 points
  6. sensio insight is a good tool and used by Drupal8 a lot since they are on symphony. Security is quite important and most important is actually a lively reporting community!!! Which means the mor people are using processwire the more vulnerabilities probably also get discovered and reported. 1. I would start using PHP 5.5 ONLY and no more provide backwards compatibility. This will increase security a lot already. Simply make a cut and release a new version which is only compatible with PHP 5.5 and higher. TYPO3 7.0 was just doing that step and it is a huge speed (it is really fast!) and a huge security improvement already! OK some modules/extensions are not working but this is a very useful cleaning processes which forces developers to review and probably adjust and upgrade their modules.DON'T hang on those people which still want to use versions lower 5.5 and their arguments. Qualified and Serious Developers keep their stuff up to date and use also hosting surroundings which would allow deploying a Processwire Version which uses only 5.5 and is no more backwards compatible to lower PHP Versions. AND it will bring you more customers this is exactly what just happens since TYPO3 7.0 has been released. People like it so much that they like to switch even it has not all the modules which are working in right now. They like the new backend the new look and most of all they like the great speed increasement and SPEED is very important - I would say even more important than Keywords and all this other SEO stuff! And not seldom they also reduce the chance of vulnerabilities of your site! 2. Security is very important criteria for customers, especially from bigger companies and smaller ones actually most likely follow the "wind" - which means as soon as they will pick up a vulnerability from whatever it is WordPress, TYPO3, Drupal, ... at least if it gets published they will use it and question if Processwire is weak and vulnerable too. What is said here about Microsoft is probably also valid for many other great systems http://secunia.com/vulnerability-review/vendor_update.html The biggest enemy is the Third Party! 3. "In my opinion a module not being submitted to the modules directory is a sign of the author a) not knowing much of the ProcessWire environment / ecosystem (which can be a bad thing), b) not considering the module ready enough for the directory (in which case it definitely isn't ready for production use), or c) the author being too lazy or busy to submit the module (which means that the support will most likely be lacking too)." Teppo well said - but have a look to reality and you will realize that many great modules are missing but they are working. Therefore another review process should be implemented. One would be to mark modules "alpha" "beta" "stable" "obsolete" instead and having the ability to review also an alpha or beta module. 4. Right now there are only a few modules which are easily to review by one person i.e. RYAN. But when Processwire will grow there probably will be 10 times as much modules and I guess RYANs main job won't be to review all those modules. Therefore I suggest in setting up a security team, to which module developers can submit there modules for review and of course those leaks which get discovered would get reported immediately. 5. Very important is IMHO Transparency! There should be a publishing process to make vulnerabilities public as soon as they had been discovered. If the security team is working successfully they usually would be able to send a fix right the way! Yes it has to be fast - very fast actually. Which means the security team needs to communicate with the module developer - take the module off for the time the vulnerability is existing - and publishing the warning so that everyone running a site with processwire and that specific module gets informed. A Dashboard which presents that information in the Processwire backend to the customer/user would help a lot, beside this secunia is a great resource. As an example here those from other CMSs: http://typo3.org/news/security-bulletins/ https://www.drupal.org/security Publish you Policy: i.e.: http://typo3.org/teams/security/extension-security-policy/ https://www.drupal.org/security-advisory-policy and actually very good and even more important - The Security Team and review procedures: https://www.drupal.org/node/1424708 and some education to learn from: http://typo3.org/teams/security/resources/ 6. Publish vulnerabilities on secunia: - Don't hesitate and show transparency! If Processwire is secure and gets fixed right the way there is absolutely nothing to hide. http://secunia.com/community/advisories/report_vulnerability/ Please send an email to vuln@secunia.com to send us your research. Information in your report should include: Affected operating system/software, including full version details How the vulnerability can be reproduced What impact the vulnerability has on the vulnerable system Any additional details that might help in the verification process -- Check out: http://secunia.com/community/advisories/search/?search=Processwire (0) - Probably because nobody is reporting vulnerabilities! http://secunia.com/community/advisories/search/?search=modx (22) - Probably not many people are reporting or they have no one reviewing the code! no transparency http://secunia.com/community/advisories/search/?search=typo3 (202) http://secunia.com/community/advisories/search/?search=joomla (604) http://secunia.com/community/advisories/search/?search=drupal (782) http://secunia.com/community/advisories/search/?search=wordpress (1038) most important is how fast actually those vulnerabilities get fixed and how the fix is available. Often in Joomla and Wordpress you will read "edit the source etc." In more mature CMS they will provide an updatedVersion to an extension or module right the way! Compare also how many vulnerabilities have not been fixed!!! - keep some ofthose infos for your "customers" they are good arguments for marketing your solution and preferred CMS! We give our customers access to those resources mentioned above and it creates work as they want to keep their sites updated and secure! And most likely they can't do it themselves - they will realize this very fast! that this is an ongoing job which will never end! 8. Keep ALL modules also those in alpha, beta, stable and even idea state available in a centralized repository and developing space. The more people will be able to use those modules BEFORE they go into production the more testing will be done and the more feedback the developer will get, the better the module will be. This is very helpfull for developers if their modules are much easier to find and it also enables other developers to HELP and get interested. Beside that it is a nice place for checking which developers are having great coding style and which not. It would make reviews of code much much easier - and translations too. i.e. https://forge.typo3.org/ ---
    2 points
  7. One of my co-workers found the cause for my problem. The suhosin.ini on our server had a max length of 64 characters and we had to increased it to 128.
    2 points
  8. So I think I'm going to change MarkupSEO back to creating "real" fields. This will allow multilanguage and has some other benefits as this module is used by a lot of you lately.
    2 points
  9. Wire Mail SMTP An extension to the (new) WireMail base class that uses SMTP-transport This module integrates EmailMessage, SMTP and SASL php-libraries from Manuel Lemos into ProcessWire. I use this continously evolved libraries for about 10 years now and there was never a reason or occasion not to do so. I use it nearly every day in my office for automated composing and sending personalized messages with attachments, requests for Disposition Notifications, etc. Also I have used it for sending personalized Bulkmails many times. The WireMailSmtp module extends the new email-related WireMail base class introduced in ProcessWire 2.4.1 (while this writing, the dev-branch only). Here are Ryans announcement. Current Version 0.8.0 (from 2024-09-25 -- initial version 0.0.1 was pushed on 2014-03-01) Changelog: https://github.com/horst-n/WireMailSmtp/blob/master/CHANGELOG.md Downlod: get it from the Modules Directory || fetch it from Github || or use the module-installer in PWs admin site modules panel with its class name "WireMailSmtp". Install and Configure Download the module into your site/modules/ directory and install it. In the config page you fill in settings for the SMTP server and optionaly the (default) sender, like email address, name and signature. You can test the smtp settings directly there. If it says "SUCCESS! SMTP settings appear to work correctly." you are ready to start using it in templates, modules or bootstrap scripts. Usage Examples The simplest way to use it: $numSent = wireMail($to, $from, $subject, $textBody); $numSent = wireMail($to, '', $subject, $textBody); // or with a default sender emailaddress on config page This will send a plain text message to each recipient. You may also use the object oriented style: $mail = wireMail(); // calling an empty wireMail() returns a wireMail object $mail->to($toEmail, $toName); $mail->from = $yourEmailaddress; // if you don't have set a default sender in config // or if you want to override that $mail->subject($subject); $mail->body($textBody); $numSent = $mail->send(); Or chained, like everywhere in ProcessWire: $mail = wireMail(); $numSent = $mail->to($toEmail)->subject($subject)->body($textBody)->send(); Additionaly to the basics there are more options available with WireMailSmtp. The main difference compared to the WireMail BaseClass is the sendSingle option. With it you can set only one To-Recipient but additional CC-Recipients. $mail = wireMail(); $mail->sendSingle(true)->to($toEmail, $toName)->cc(array('person1@example.com', 'person2@example.com', 'person3@example.com')); $numSent = $mail->subject($subject)->body($textBody)->send(); The same as function call with options array: $options = array( 'sendSingle' => true, 'cc' => array('person1@example.com', 'person2@example.com', 'person3@example.com') ); $numSent = wireMail($to, '', $subject, $textBody, $options); There are methods to your disposal to check if you have the right WireMail-Class and if the SMTP-settings are working: $mail = wireMail(); if($mail->className != 'WireMailSmtp') { // Uups, wrong WireMail-Class: do something to inform the user and quit echo "<p>Couldn't get the right WireMail-Module (WireMailSmtp). found: {$mail->className}</p>"; return; } if(!$mail->testConnection()) { // Connection not working: echo "<p>Couldn't connect to the SMTP server. Please check the {$mail->className} modules config settings!</p>"; return; } A MORE ADVANCED DEBUG METHOD! You can add some debug code into a template file and call a page with it: $to = array('me@example.com'); $subject = 'Wiremail-SMTP Test ' . date('H:i:s') . ' äöü ÄÖÜ ß'; $mail = wireMail(); if($mail->className != 'WireMailSmtp') { echo "<p>Couldn't get the right WireMail-Module (WireMailSmtp). found: {$mail->className}</p>"; } else { $mail->from = '--INSERT YOUR SENDER ADDRESS HERE --'; // <--- !!!! $mail->to($to); $mail->subject($subject); $mail->sendSingle(true); $mail->body("Titel\n\ntext text TEXT text text\n"); $mail->bodyHTML("<h1>Titel</h1><p>text text <strong>TEXT</strong> text text</p>"); $dump = $mail->debugSend(1); } So, in short, instead of using $mail->send(), use $mail->debugSend(1) to get output on a frontend testpage. The output is PRE formatted and contains the areas: SETTINGS, RESULT, ERRORS and a complete debuglog of the server connection, like this one: Following are a ... List of all options and features testConnection () - returns true on success, false on failures sendSingle ( true | false ) - default is false sendBulk ( true | false ) - default is false, Set this to true if you have lots of recipients (50+) to ($recipients) - one emailaddress or array with multiple emailaddresses cc ($recipients) - only available with mode sendSingle, one emailaddress or array with multiple emailaddresses bcc ($recipients) - one emailaddress or array with multiple emailaddresses from = 'person@example.com' - emailaddress, can be set in module config (called Sender Emailaddress) but it can be overwritten here fromName = 'Name Surname' - optional, can be set in module config (called Sender Name) but it can be overwritten here priority (3) - 1 = Highest | 2 = High | 3 = Normal | 4 = Low | 5 = Lowest dispositionNotification () or notification () - request a Disposition Notification subject ($subject) - subject of the message body ($textBody) - use this one alone to create and send plainText emailmessages bodyHTML ($htmlBody) - use this to create a Multipart Alternative Emailmessage (containing a HTML-Part and a Plaintext-Part as fallback) addSignature ( true | false ) - the default-behave is selectable in config screen, this can be overridden here (only available if a signature is defined in the config screen) attachment ($filename, $alternativeBasename = "") - add attachment file, optionally alternative basename send () - send the message(s) and return number of successful sent messages debugSend(1) - returns and / or outputs a (pre formatted) dump that contains the areas: SETTINGS, RESULT, ERRORS and a complete debuglog of the server connection. (See above the example code under ADVANCED DEBUG METHOD for further instructions!) getResult () - returns a dump (array) with all recipients (to, cc, bcc) and settings you have selected with the message, the message subject and body, and lists of successfull addresses and failed addresses, logActivity ($logmessage) - you may log success if you want logError ($logmessage) - you may log warnings, too. - Errors are logged automaticaly useSentLog (true | false) - intended for usage with e.g. third party newsletter modules - tells the send() method to make usage of the sentLog-methods - the following three sentLog methods are hookable, e.g. if you don't want log into files you may provide your own storage, or add additional functionality here sentLogReset () - starts a new LogSession - Best usage would be interactively once when setting up a new Newsletter sentLogGet () - is called automaticly within the send() method - returns an array containing all previously used emailaddresses sentLogAdd ($emailaddress) - is called automaticly within the send() method Changelog: https://github.com/horst-n/WireMailSmtp/blob/master/CHANGELOG.md
    1 point
  10. FieldtypeMatrix and InputfieldMatrix Modules Directory: http://modules.processwire.com/modules/fieldtype-matrix/ GitHub: https://github.com/kongondo/FieldtypeMatrix The module Matrix enables you to save data from a 2D-Matrix table. The rows and columns of the matrix table are made up of pages retrieved via a ProcessWire selector or via a page field selection of parent pages. The matrix values are made up of the data input in the matrix cells, i.e. the 'intersection of rows and columns'. Example Usage You have Products whose prices vary depending on colour, size, material, etc. Using the Fieldtype, you can create a table with rows made up of colours and columns made up of sizes the combination of each making up their respective values (in this case price). So rather than creating multiple text fields to do the following: Colour Size Price Red Small £10 Red Medium £20 Red Large £30 Red X-large £35 Green Small £9 Green Medium £15 Etc... You can instead have the following in one field: Small Medium Large X-Large Red £10 £20 £30 £35 Green £9 £15 Blue Etc... Yellow Purple If you set a selector in the Field's settings, to retrieve pages to build your matrix's rows and columns, it follows that all pages using the template the Fieldtype is attached to will have identical rows and columns. In some cases, this could be the intention. For instance, you might have 'Car' pages, e.g. Audi, Volvo, Ford, Citroen, Mazda, BWM, etc., each of which uses a 'Cars' template that has a single FiedltypeMatrix called 'car_attributes'. If you set a selector to build the Fieldtype's rows and columns, your users can easily compare the cars based on a combination of different values. The following matrix table best illustrates this: Type Engine Size Fuel Efficiency Carbon Emissions Warranty Road Tax Price 1994 Audi brand 1 values, etc. 2000 Audi brand 2 2006 Audi brand 3 2012 Audi brand 4 Each of your car pages would have similar matrices. This allows you to make easy but powerful queries. Such a setup allows you to compare within and across car brands. Say you wanted to find out which car(s) offered the best value for money given certain parameters such as warranty, emissions etc. You can easily make such comparisons (see code below). You can also compare within one car type, e.g. which brand of BMWs does best in what area...The possibilities are endless. In the database, Rows and column pages data are stored as their respective page->id. Matrix-values store any data (varchar(255)). If instead you wanted a template's pages to each have a matrix built of different rows and columns, you would have to name a Multiple Page Field (attached to the same template as the as your matrix field) in the matrix field's settings. When editing those pages, your matrix table's rows and columns will be built using the published children pages of the 2 pages you select in the Multiple page field.. The module allows the creation of matrix tables of any sizes (rows x columns). The rows and columns dynamically grow/shrink depending on the addition of row/column pages that match what you set in the matrix field's settings (see its 'Details Tab'). Please note that, if such pages are deleted/trashed/hidden/unpublished, their data (and presence) in the matrix are also deleted. Entering values in the matrix You have three choices: Manually entry Uploading a comma delimited (CSV) file. This can be delimited by other characters (tab, pipe, etc); not just commas Copy-pasting CSV values. (Tip: you can copy paste directly from an Excel spreadsheet. Such values will be 'tab-delimited'). In addition, if your server supports it, in the field's settings, you can enable the use of MySQL's fast LOAD DATA INFILE to read and save your submitted CSV values. Note that for large tables, you may have to increase your PHP's max_input_vars from the default 1000 otherwise PHP will timeout/return an error and your values will not be saved. I have successfully tested the module with up to ~3000+ values (10x350 table), the Fieldtype is not really optimised (nor was it intended) to handle mega large matrix tables. For such, you might want to consider other strategies. Install Install as any other module. API + Output A typical output case for this module would work like this: The matrix's rows, columns and values are subfields of your matrix's field. So, if you created a field called 'products' of the type FieldtypeMatrix, you can access as: product.row, product.column and product.value respectively foreach($page->matrix as $m) { echo " <p> Colour: $m->row<br /> Size: $m->column<br /> Price: $m->value </p> "; } Of if you want to output a matrix table in the frontend: //create array to build matrix $products = array(); foreach($page->matrix as $m) $products[$m->row][$m->column] = $m->value; $tbody ='';//matrix rows $thcols = '';//matrix table column headers $i = 0;//set counter not to output extraneous column label headers $c = true;//set odd/even rows class foreach ($products as $row => $cols) { //matrix table row headers (first column) $rowHeader = $pages->get($row)->title; $tbody .= "<tr" . (($c = !$c) ? " class='even' " : '') . "><td class='MatrixRowHeader'>" . $rowHeader . "</td>"; $count = count($cols);//help to stop output of extra/duplicate column headers foreach ($cols as $col => $value) { //matrix table column headers $columnHeader = $pages->get($col)->title; //avoid outputting extra duplicate columns if ($i < $count) $thcols .= "<th class='MatrixColumnHeader'>" . $columnHeader . "</th>"; //output matrix values $currency = $value > 0 ? '£' : ''; $tbody .= "<td>" . $currency . $value . "</td>"; $i++; } $tbody .= "</tr>"; } //final matrix table for output $tableOut = "<table class='Matrix'> <thead> <tr class=''> <th></th> $thcols </tr> </thead> <tbody> $tbody </tbody> </table>"; echo $tableOut; The module provides a default rendering capability as well, so that you can also do this (below) and get a similar result as the first example above (without the captions). echo $page->matrix; Or this foreach($page->matrix as $m) { echo $m; } Finding matrix items The fieldtype includes indexed row, column and value fields. This enables you to find matrix items by either row types (e.g. colours) or columns (e.g. sizes) or their values (e.g. price) or a combination of some/all of these. For instance: //find all pages that have a matrix value of less than 1000 $results = $pages->find("products.value<1000"); //find some results in the matrix (called products) of this page $results = $page->products->find("column=$country, value=Singapore");//or $page->products->find("column=$age, value>=25"); //$country and $age would be IDs of two of your column pages Other more complex queries are possible, e.g. find all products that are either red or purple in colour, come in x-large size and are priced less than $50. Credits @Ryan on whose Fieldtype/InptufieldEvents this is largely based @charger and @sakkoulas for their matrix ideas Screens Field Details Tab Inputfield Larger matrix table Example output
    1 point
  11. This is a very simple way to display some instructions to the admin users. Before starting, you need to write some docs; they can be a hidden branch of your page tree, using basic-page, or a different template of your choosing. You should make each subject it's own page under the docs so you can output each one under an accordion trigger. Required Module: Admin Custom Pages 1.) Follow all instructions to install the module; Also add the ACP_scripts_and_styles field to the admin template. 2.) Make a new page under admin, called Docs or whatever; assign the process as described in the module instructions. 3.) Make a template in your themes directory to generate the output of the docs page. 4.) Select that template from the page select in the admin custom page you created. 5.) also make a folder to keep your admin custom pages scripts and styles; 6.) create a css file to use for the display output and some basic styles (like ol, ul li etc..) 7.) Add the custom css file to your ACP_scripts_and_styles field. You can use any output you want, but i'm using a nested accordion, which is provided here: http://tympanus.net/codrops/2013/03/29/nested-accordion/ this is the content of the admin custom page: <?php $docs = $pages->get(4259); ?> <div id="docs"> <ul id="cbp-ntaccordion" class="cbp-ntaccordion"> <?php foreach($docs->children as $doc) { ?> <li> <h3 class="cbp-nttrigger"><?php echo $doc->title ?></h3> <div class="cbp-ntcontent"> <?php echo $doc->body;?> </div> </li> <?php } ?> </ul> </div> <script src="<?php echo $config->urls->templates ?>_admin_custom/js/jquery.cbpNTAccordion.min.js"></script> <script> $( function() { $( '#cbp-ntaccordion' ).cbpNTAccordion(); } ); </script> you'll also want to add the provided css, js and fonts that come with the Nested Accordion; in the css file you'll need to point the fonts to the actual font directory, for example: /site/templates/_admin_custom/fonts/icomoon_arrows/icomoon.eot it should come out looking something like this: *if you are using Reno theme, you can customize the icon, like for example fa-book, which is used in this example: -- Thanks & Credits to Diogo for originally creating the ACP module, and for Nico for getting it to work with the new admin theme system...
    1 point
  12. Update: Such a module already exists: kongondo's Module Menu Builder When you look at other CMS such as Wordpress or Drupal, no matter what you think of them, they share a feature that would suit ProcessWire very well: The seperation of menus and content structure via backend. While this is kind of possible programmatically, in the template via MarkupSimpleNavigation, both Drupal and Wordpress have their take on a “Menu Creator” in their backends, where editors could compose their menus, consisting of references to pages or external links: While not part of these screenshots, both visual editors provide the option to nest menu items. As you maybe have noticed, I’m kind of experimenting with modules right now And I’m eager to learn more about module creation and the inner architecture of PW. But: the longer I thought about this “Visual Menu Module” idea the more I noticed it’s still far ahead of my abilities. In the following I’ll write down how I would approach such a module. It would be really helpful for my understanding of modules and programming itself if you can give me feedback… concerning if such a module worthwhile - or I’m misjudging the demand if it’s possible the way it is described if there are some quirks or factors I haven’t thought of Thanks in advance! And here we go: The module itself would establish a process, let’s call it ProcessCustomMenus. During module installation, the plugin would create a subpage of “Setup” within the admin branch of ProcessWire backend main navigation, “Custom Menus”. Navigating on “Custom Menus”, there would be a possibility to list, create and edit the custom menus. Technically, all custom menus would be child pages of said new “Custom Menus” page. Then, three new templates would be necessary: customMenu, customMenu_pageReference and customMenu_externalReference. customMenu is used for direct children of “Custom Menu”, while the other to templates will serve as items on a particular menu. Phew, hard to describe. Here’s a screenshot: For starters, customMenu_pageReference and customMenu_externalReference could have only two fields each: title and pageArray (for internal references), or title and text (for external references). Later one could try to save the menu item nesting state in an additional field. On the template side, a named custom menu could be output as easy as: $modules->get(“MarkupCustomMenus”)->renderCustomMenu(“named_menu”, $options) …where $options could be an array full of further markup config. Of course, the content of “Custom Menus” in backend should be as easy as in the Drupal and Wordpress examples above, and appareled with all the interface magic jQuery UI has to offer, and also maybe ASM select (though I’m not sure how to achieve nesting with ASM) or other ProcessWire backend concepts. So, what do you think?
    1 point
  13. A clean, Basic Foundation website, build using Processwire. Team Training For Professionals The client is happy with the site, and using Repeaterfields and Hannacode makes adding FAQ's piece of cake! This was am "in between" hobby project, but as always took much longer estimated.
    1 point
  14. Not yet tested this one, but it looks very powerful! Great work Kongondo!
    1 point
  15. I've been looking at creating my own templates and test pages and adding some much more lo-fi / basic code. As Kongondo says, the templates provided are just examples and you could output any markup you wish by making your own templates. For example, if you wish to create your own blog-post.php template, you can make a template called blog-post-custom.php etc and manually call a few fields. Here's the body of an extremley basic blog post template. It relies less on variables within other files and includes. <!-- Get the title in a H3 tag--> <h3><?php echo $page->title; ?></h3> <!-- Get the body --> <?php echo $page->blog_body; ?> <!-- Get the comments --> <?php echo $page->blog_comments->render(); ?> <!-- Get the comment form --> <?php echo $page->blog_comments->renderForm(); ?> Likely it bypasses much Kongondos genius but this would actually suffice for my requirements. I'm not sure how I would grab the number of comments this page has but I'll figure it out.
    1 point
  16. I would like to do a request. Is it possible to remove the line breaks? <title>titel</title><meta name="keywords" content="voorbeeld, voorbeeld, voorbeeld"> <meta name="description" content="Dit is de omschrijving"> <meta name="image" content=""> <meta name="canonical" content="http://www.testpagina/"> <meta name="generator" content="ProcessWire 2.5.3"> <meta name="author" content=""> <meta name="robots" content="index, follow"> <meta name="og:site_name" content=""> <meta name="og:title" content="titel"> <meta name="og:url" content=""> <meta name="og:description" content="Dit is de omschrijving"> <meta name="og:type" content="website"> <meta name="og:image" content=""> <meta name="twitter:card" content="summary"> <meta name="twitter:site" content="@"> <meta name="twitter:title" content="titel"> <meta name="twitter:url" content=""> <meta name="twitter:description" content="Dit is de omschrijving"> <meta name="twitter:image" content="">
    1 point
  17. @kongondo: had to check, and apparently column is a reserved word, row and value should be fine. Either way, prefixed values make sense after all, no point in having only one prefixed. Also, I kind of prefer matrix_* over m*, and matrix_value over data, so wouldn't chance anything to be honest
    1 point
  18. @mike 1. It's not possible to add a extra link as overview like you mention. This module parses your tree and needs physical pages to work with. If you really need this you have to build a page for it or use javascript to add the overview link to the list (I'm doing this in one project). 2. The parent of the active entry will get the class as defined in option "parent_class" so default is <li class="parent"> It's all documented here http://modules.processwire.com/modules/markup-simple-navigation/ This module adds classes to li's and not anchors for a good reason as that is much more flexible. There's no option to change that. So if you need such special cases you're up to use javascript. Or us php str_replace() to replace something on the returned markup. Let's see if you want to change class="parent" for parent li's you'd maybe do this $markup = $nav->render($options); $markup = str_replace("<li class='parent'", "<li data-current", $markup); Also there's some method to hook into and change things on items or lists, there's plenty examples in this thread and in the doc.
    1 point
  19. @pwired, there's no way to track that via a client side webdev tool like firebug or any other, it's just not possible (seems logical). You need to search on filesystem either directly on server via grep command or download all files locally and use some search provided by a IDE or Code editor like sublime text.
    1 point
  20. Greetings, First -- welcome to ProcessWire. I think there might be a simple solution to your situation. But first, tell me this: are you planning to use ProcessWire as your sole CMS for this project, or do you plan to maintain another CMS along with it? If you are planning to make a full switch to ProcessWire, I would suggest doing a one-time conversaion of the database into ProcessWire. Then from that point forward you are all set. Just for background, I have converted Joomla, WordPress, and Shopify databases into ProcessWire. You can do it. Just post here and people will help. As far as learning MySql, this could be a great opportunity to do just that! Thanks, Matthew
    1 point
  21. Hey, new version is almost finished and is going to be released in an hour I guess. Most of your issues should be solved in this And the image field is used for open graph and twitter cards. And I normally do _stuff for tabs to but I thought it might be a little bit better to have the same schema for all of the seo fields that get generated automatically (and it's easier to delete them afterwards)
    1 point
  22. Adrian, Your changes made the difference. It works great now. Thanks a million. Best Regards, Charles
    1 point
  23. Found the problem. The Blog page is linked to blog.php. Changed $content .= $blog->renderPosts("limit=$limit"); to $content .= $blog->renderPosts("limit=$limit,true"); Sorry...., dumb of me. Got to learn more about the structure of the template demo files.
    1 point
  24. @kongondo, this looks great, thanks for making it available! Will take a closer look soon, but just a (very) minor note at this point: I can't help wondering why the subfields are prefixed with matrix_ -- doesn't honestly matter that much, but I fail to see much value in that either, just slight increase in verbosity compared to non-prefixed alternatives
    1 point
  25. Hi Spoetnik Interesting theme they have. I would recommend that you check your site again with gtmetrix and apply the changes they suggest. It will help you to get much more speed out of your site. http://gtmetrix.com/reports/ttfp.eu/gg834XCN - Try to achieve values higher than 95% in Pagespeed and Processwire and a loading time less than 1.2 sec Until now the site also has no SEO optimization - The module Nico is developing woudl be a great instant help for that problem too. Just install it and apply the seo values mentioned in there - fill out the fields. Most of all I would recommend enabeling gzip compression and as a next step using a supercharger like cloudflare to speed up loading times and to improve security and even give your customer some more nice features for free - as he needs to communicate with customers - i.e. uservoice etc. check it out. http://cloudflare.com Thanks for sharing
    1 point
  26. This is a good idea Nico especially also whenyou have lots of pages which use MarkupSEO. And Multilanguage is a must for modern SEO in Asia. Thanks!
    1 point
  27. Hi @toothpaste, To prove it out, why not try something like this $posts = $pages->find('template=blog-post, limit=5'); and see whether you get the page posts you expect in the page array. If you do, then try this: $content .= $blog->renderPosts($posts, true);
    1 point
  28. Hi @kathep, welcome to PW and the forums. As with the most things here, there are no "right way" to do it. There are a few more or less equal but different solutions possible. What come into my mind are three variations: a) simply going with single pages b) going with repeaters c) going with Profields Pagetable I would go with single pages: 1) build a page called tools or something that only serves as parent for stuff that is not used to be displayed directly to the forntend. Set the page to hidden. 2) Build a template called category, it only needs a title field I think create a page under tools called categories that should serve as parent for your categories build child pages under categories that have the template category and the title are the names of your categories you need 3) Build a template called quotes, build the fields you need to be on a quotes page: quote_text = textarea quote_author = text quote_category = page, best is to use it with ASM select!, the source for it is the category parent! etc and assign them to the template Build a page under tools called quotes as parent for all single quote pages create your quote pages there (if you have to many for a manually creation, there are also automated import solutions available) If you have all setup you can get the quotes from every where in PW with a selector like this // get all quote pages $quotes = $pages->get("/tools/quotes/")->children(); // get all quote pages of a specific category $quotes = $pages->get("/tools/quotes/")->find("quote_category.title=category1"); // get all quote pages of a few specific categories $quotes = $pages->get("/tools/quotes/")->find("quote_category.title=category1|category2|category3"); // to get only one random out of those collections you call ->getRandom() at the end $quote = $pages->get("/tools/quotes/")->find("quote_category.title=category1|category2|category3")->getRandom(); If you get stuck at some point with this, come back and tell us.
    1 point
  29. Update: version 0.0.3 Small but important update to correct oversight whereby records with empty values were being saved to the database, thx @netcarver.
    1 point
  30. @Steve, Good catch about empty values! Don't know how I mised that! I have corrected it in Version 0.0.3 (post here soon), thanks! Memory issue: That was my next question. I would like to do/see some real world tests....+ there's also PHP post limits...Would appreciate if anybody could help test , thanks.
    1 point
  31. @kongondo, is there any need to store the empty results? Just wondered as once you get into the world of combinatorials things quickly get memory hungry big; and PHP associative arrays aren't exactly the world's most efficient storage format. Any idea how this fieldtype works out memory wise?
    1 point
  32. That turned out (later) to be the easy bit . They are stored similar to Page Fields...(see second screenshot below) Matrix array (see post below - we use this only for grabbing db values to later manipulate to build matrix cells/intersections. We use a different array for saving) Matrix db table (see update below [version 0.0.3] about avoiding saving records with empty values)
    1 point
  33. I've been using Mandrill for a year now for various projects and can't rate them highly enough. They're great for sending emails using the SMTP classes built for ProcessWire. For example, on several occasions I've had IPs blocked by Hotmail because someone who subscribed to something marked an email as spam (yes, users do silly things like forget what they signed up to or don;t just use the unsubscribe links) and Mandrill saves you a lot of hassle by a) not letting you send to those users again if the email bounced or was marked as spam and b) ensuring your IP isn't blocked to the rest of Hotmail (or whichever other service this might happen with - isn't Hotmail Outlook.com now anyway?). It also has some great webhooks so you can write some code to let you know which customers aren't interested within your own application. So yeah, great service that does a lot for you, lets you have sub-accounts for each client and all round protects your deliverability on business-critical applications.
    1 point
  34. I dunno, I like the idea of me being the weakest link in my work
    1 point
  35. Update: version 0.0.2 Added ability to reuse a single matrix field across pages/templates to build unique matrix tables on a page by page basis. This is achieved by specifying the name of a Multiplepages select field in the Fieldtype settings (Details Tab). It allows you to select row and column parent pages from within the page containing the matrix itself. The child pages of these parents are used to build the matrix. This setting overrides the Row and Column selector settings of the fieldtype. Example usage: Create a Multiplepages field and call it, for example, 'product_select'. Set it up as you wish (e.g. custom PHP, selectors, etc for selectable pages). You may wish to use ASM select to make things prettier/easier below. Add it to the same template(s) where you will be using a matrix field. In your matrix field's Details Tab, specify the name of the page field (i.e. 'product_select') under the 'Matrix Row and Column Parent Pages' setting. Edit the page where you will be building a matrix table. Select 2 pages in your 'product_select' whose child pages will be used to create your matrix rows and columns. The order is important! The first selected page will be assumed to be the row pages parent and the second one the column pages parent. Any additional pages here will be ignored. Save your page and your matrix table will be built using the children of the selected parent pages. Note: The usual error checking will be done and 'thrown' (e.g. if parent pages do not have children, if your specified page field is not a page field/does not return a PageArray, etc. Note 2: You can swap/change the row/column pages in your page field (product_select) HOWEVER, all previously saved values will be deleted(!) on save and your matrix table rebuilt to reflect the new specified row/column structure. Todo/think about Copy values from Excel and directly paste this in a similarly structured matrix table Export matrix table? 1-click clear all values entered in a matrix table Etc? Download: https://github.com/kongondo/FieldtypeMatrix Screens Named Page Field to select rows and columns parent pages Row and Column parent pages selection in a specified Page Field Reusing a single matrix field on a different page(s)
    1 point
  36. Peter & Sephiroth, It is trivial to add extra fields pulled from any PW page into the generated output without having to modify the blog module code. When you call the renderPost() function (or any of the blog functions), you'll get the markup. Using something like QueryPath (http://querypath.org/), you can convert your blog markup into a DOM object that responds to jQuery-like CSS3 selectors and modify the markup, adding whatever you want into the DOM tree. When you are done, then simply call the html() method on the modified QueryPath object and echo the converted markup into your PW template. I hope this helps.
    1 point
  37. What about modules in processwire? Everything safe? Maybe we need a tag [security-checked] given by an accredited team of PW developers.
    1 point
  38. Soma, as a master of sarcasm I would have thought you noticed mine sarcasm
    1 point
  39. Andi, nico has build an SEO tool not an encyclopedia.
    1 point
  40. My, and a guess kongondos intention as well, of such a module would not be to replace or deny PW page tree approach (or even tricking someone), but providing an additional option to create a menu. Sometimes menus are needed which contain a wild bunch of references across the site, as well as some external links. The "virtual tree" approach is possible, but another interface solution would be better in some cases. That's just what motivated me to describe this approach (and I guess that motivated kongondo to write such a module in the first place, a year ago )
    1 point
  41. Oh good! All that typing from everyone is definitely worth it then!
    1 point
  42. Very nice - It was quite easy to add the 2 subpages. I added a Hook after 'save' and with $hookEvent->arguments[0] you get the page and add the Subpages if necessary Module Code: public function init() { // add a hook after the $pages->save $this->pages->addHookAfter('save', $this, 'createSubPagesForCompany'); } /** * Hook into the pages->save method and create two subpages if necessary * */ public function createSubPagesForCompany($event) { $page = $event->arguments[0]; $templates = wire('templates'); // only for template 'company' // create two subpages 'engagement_list' & 'address_list' if necessary if (!$page->isTrash && $page->template->name == 'company'){ if ($page->children('template=engagement_list')->count()==0){ // create engagement list $eng_list = new Page($templates->get('engagement_list')); $eng_list->parent = $page; $eng_list->name = 'engagements'; $eng_list->save(); $this->message("Engagement Liste erstellt."); } if ($page->children('template=address_list')->count()==0){ // create address list $addr_list = new Page($templates->get('address_list')); $addr_list->parent = $page; $addr_list->name = 'adressen'; $addr_list->save(); $this->message("Adressliste erstellt."); } } }
    1 point
  43. Recently I've been working on a site where it seemed like it was going to be impossible to keep the page tree and the needs of the site's main menu in harmony; So to solve this I setup a separate page tree under a hidden page called 'Main Menu', with each menu item having three fields: title, menu-link-page, and menu-link-url. All of the menu items are also hidden, so the code below uses the include=all parameter when getting the pages for the tree. To generate the main menu markup, i adapted the great code that was developed by Soma for Joss's bootstrap menu, and modified it to output links to the menu-link-page or menu-link-url; (Entering a value in the menu-link-url field overrides any selection in the menu-link-page.) This solution has enabled me to setup the menu exactly how the site needs it, even if the menu heirarchy is not the same as the page heirarchy, and has solved a lot of problems and made things easier for this scenario. For example, menu items can easily contain external URLs, to subdomain pages, or other related site's pages. (In this case the client has a separate web store for selling parts). Also, all of the parent menu items had to use a javascript:void() as the href, in order for the accordion version to work right on mobile; So this was easy to do by putting that into the menu-item-link field. In the code below, page #1271 contains the menu tree, so it is specified as a parameter to the $root variable. I think this sort of setup, using a custom menu tree, could solve a lot of the questions I've seen recently on the forum; I probably wouldn't use this technique on small sites since it is more work, but for larger ones where you might need a lot of menus, this could be helpful. Also, if you had to setup a Mega Menu, with images and icons, this might make it easier to manage. <?php /** * render custom markup menu for bootstrap nested navigation * * @param PageArray $pa pages of the top level items * @param Page $root root page optional, if you use other root than home page (id:1) * @param string $output for returned string collection * @param integer $level internally used to count levels * @return string menu html string */ function renderChildrenOf($pa, $root = null, $output = '', $level = 0) { if(!$root) $root = wire("pages")->get(1); $output = ''; $level++; foreach($pa as $child) { $class = ''; $has_children = count($child->children('include=all')) ? true : false; if($has_children && $child !== $root) { if($level == 1){ $class .= 'parent'; // first level boostrap dropdown li class //$atoggle .= ' class="dropdown-toggle" data-toggle="dropdown"'; // first level anchor attributes } } // make the current page and only its first level parent have an active class if($child->menu_item_page === wire("page")){ $class .= ' active'; } else if($level == 1 && $child !== $root){ if($child->menu_item_page === wire("page")->rootParent || wire("page")->parents->has($child)){ $class .= ' active'; } } $class = strlen($class) ? " class='".trim($class)."'" : ''; if($child->menu_item_url) {$childlink = $child->menu_item_url; } else { $childlink = $child->menu_item_page->url; } $output .= "<li$class><a href='$childlink'>$child->title</a>"; // If this child is itself a parent and not the root page, then render its children in their own menu too... if($has_children && $child !== $root) { $output .= renderChildrenOf($child->children('include=all'), $root, $output, $level); } $output .= '</li>'; } $outerclass = ($level == 1) ? "accordmobile" : ''; return "<ul class='$outerclass'>$output</ul>"; } // bundle up the first level pages and prepend the root home page // $root = $pages->get(1); // $pa = $root->children; // $pa = $pa->prepend($root); // Set the ball rolling... // echo renderChildrenOf($pa); // example with pages further down in the tree $root = $pages->get("1271"); $pa = $root->children('include=all'); // $pa = $pa->prepend($root); // add the root as the second parameter echo renderChildrenOf($pa,$root);
    1 point
×
×
  • Create New...