Leaderboard
Popular Content
Showing content with the highest reputation on 10/19/2015 in all areas
-
Media Manager Released 31 March 2016 https://processwireshop.pw/plugins/media-manager/ Documentation http://mediamanager.kongondo.com/ As of 10 May 2019 ProcessWire versions earlier than 3.x are not supported ******************************************************* ORIGINAL POST ******************************************************* API Example (frontend; will be added to documentation site) Accessing and outputting the contents of the MediaManager field(s) in your template is quite simple. The fields are accessed like many other ProcessWire fields. The fields return an array of type MediaManagerArray that need to be looped to output each media within. Assuming you created a field of type MediaManager named 'media', you can loop through it for a given page as shown below. @note: Each MediaManager object has the following 5 basic properties: DATABASE (saved properties) 1. id => pageID of the page where the media lives (hidden in admin and not important to know about) 2. type => integer denoting media type (1=audio; 2=document; 3=image [for variations this will be 3x, where x is the number of the variation of an original image]; 4=video) RUNTIME 3. typeLabel => user friendly string denoting media type (audio, document, image, video) 4. media => a ProcessWire Image/File Object including all their properties (ext, filesizeStr, height, width, description, tags, filename, basename, etc.) 5. title => title of media (@note: this is the title of the page where the media lives; may or may not be the same as the name of the media file itself). This can be used as a user-friendly name for your media $media = $page->media;// returns a MediaManagerArray. Needs to be looped through foreach ($media as $m) { echo $m->id;// e.g. 1234 (hidden page in /admin/media-manager/media-parent/) echo $m->type;// e.g. 3 (a media of type image) OR 1 (a media of type audio) echo $m->typeLabel;// e.g. 'document' (i.e. type would be 2) echo $m->title;// e.g. 'My Nice Trip' (whose media file could be my-nice-trip.mp4) /* @note: - $m->media returns an object; either a ProcessWire Image (for image media) or File object (for audio, document and video media) - This means you have access to all the properties of that object, e.g. ext, tags, description, url, filename, basename, width, height, modified, created, filesize, filesizeStr, etc as well as associated methods, e.g. size() */ echo $m->media->tags; } // only output images foreach ($media as $m) { if($m->typeLabel =='image') { echo "<img src='" . $m->media->size(100,75)->url . "'><br>"; } } // There's also a toString() method so you can do: echo $page->media; /* All your media will be output wrapped in appropriate HTML tags, i.e.: audio: <audio></audio>; document: <a></a>; image: <img>; video: <video></video>; */ ******************************************************* ORIGINAL POST ******************************************************* The topic of a central media manager feature for ProcessWire has come up several times: https://processwire.com/talk/topic/4330-get-image-from-other-pages-via-images-field/ https://processwire.com/talk/topic/4330-get-image-from-other-pages-via-images-field/?p=42578 https://processwire.com/talk/topic/4330-get-image-from-other-pages-via-images-field/?p=42582 https://processwire.com/talk/topic/425-file-manager/ https://processwire.com/talk/topic/425-file-manager/?p=13802 https://processwire.com/talk/topic/425-file-manager/?p=13861 https://processwire.com/talk/topic/10763-asset-manager-asset-selector/ More recently, regarding my Visual Page Selector module, I have been asked several times why the module does not have an in-built feature to upload images. There's two camps on the topic of a central media manager: those who like them (especially those coming in to PW from other CMSes) and those who don't like them (primarily because of the chaotic way some CMSes (dis)organise their media management) . I think that we can have our cake and eat it too! If done the right way, closely following the principles of and harnessing the power of ProcessWire, we can have a well-implemented, organised, feature-rich, site-wide media manager. Introducing Media Manager: (a commercial module) Alongside a number of modules I am currently working on (both free and commercial), I have been developing a centralised Media Manager for ProcessWire. Before you cast the first stone, no, this is not going to be a one-large-media-bucket as in other CMS where it gets very messy very quickly . In the backend things are neatly stored away, yes, in pages. However, those are pages you will not see (just like repeater pages). Before anyone has a go at pages, remember a page is not that thing you see on the ProcessWire Tree (that's just its visual representation); A page is a record/row in the database . For the end-user of Media Manager, all they will see is the 'familiar media bucket' to select their media from. As long as it works efficiently, I don't think they care about the wizardry behind the scenes . The module allows for the comprehensive management of several media types: Audio Video Images Documents Each media type will be handled by its own sub-module so the user can pick and install/choose the type of media management they want. Features include: Access controls Centralized uploads of media Bulk management of media: tag, delete, describe, replace, etc. Bulk upload: zip; scan, single Quick upload in page edit mode Usage stats across pages (maybe?) Etc.. Would love to hear your thoughts and any feature suggestions. I think there's enough demand for such a module. If not, please let me know so that I can instead focus on other things , thanks. How other CMS do it The more efficient (PW) way of doing it11 points
-
Have you guys seen http://en.arguman.org/? I find it a very interesting experiment from a developer point of view.3 points
-
I hope they can keep it a good platform for argumentation, but they would be very lucky if that happens. People on the internet tend to lower the quality of open content very fast, especially when discussing general subjects. Edit: Ivan, don't thank me, thank https://www.producthunt.com/3 points
-
You're welcome. I feel ya, I really do. That's the thing with this open source stuff we all like. I've have some outstanding issues (1, 2) as well. But we've created workarounds. When a solution pops up we fix it for good. Using open source software is an risk to be assessed, but than again I have never ever used software which didn't have it's bugs/complications. Even commercial software has its quirks or bugs which might not be a top priority to the company which owns the software. addition #1: I have to state here that I've never ever had any business critical trouble with ProcessWire that didn't was solvable in one way or another. I've build shops, imported or exported all kinds of stuff, connected ProcessWire through all kinds of API's, made websites which generated massive income either direct of through lead generating. They are all up and running and performing really good. That being not a real web developer says a lot about the system. Therefore I accept a few quirks here and there. In the end they are likely to be solved or we outgrown into another solution based on ProcessWire.3 points
-
Thanks Bernhard - your module looks great. I also put together something for this task myself. I just added it to my gists: https://gist.github.com/adrianbj/5dc1c00f1617b2639319 It allows you to do something like this in a field's description or notes text: [Click Here]({page.parent.url}) This will give you a "Click Here" link to the parent page. Of course you can also use "name", "title", and any other field from the current page, or it's parent, or parent above that. I haven't needed it yet, but I was thinking it might be nice to be able to do {page[xxxx].parent.title} so you can specify the ID of the page you want to reference. Maybe at some point I'll add that, or if anyone out there would make use of it, let me know and I'll add it sooner. While not as flexible as your module, it requires no setup so it really depends on what you need.3 points
-
Hi all, I thought I'd take this opportunity to announce a module I've been working on for a private project. Although it's not yet complete, I thought I'd take the time out to see if anyone would be interested in it. I only have the module locally on a test site, so if there is any interest, I can upload it somewhere suitable and maybe others can add to it, provide feedback etc. What is HermodBB? Hermod (messenger of the Norse gods) BB (Bulletin Board) is a module that installs a selection of templates and fields that you'd expect for a frontend forum. It also provides some methods to easily save topics and comments. All topics and comments (replies) are simply pages, and are organised like can be seen in the following image. Each forum has checkbox permissions for viewing, posting, pinning etc (see image below). These permissions can then be verified with some simple code (see below). // Use the helper method to pull a list of forum pages $forums = $hbb->forumsRender(); foreach ($forums as $forum) { // Only show the forums to those that are allowed to view them $rolesForumView = $forum->hbb_forum_view; if ($rolesForumView->has('id=' . $user->roles)) { // User has view access for the forum } } HermodBB also makes it easy to add comments to other pages, i.e articles, blogs etc. Comments are added as sub-pages, just like they are for topics. What HermodBB doesn't do HermodBB does not dictate any markup or sanitization. Any sanitization method can be used, and each topic and comment can easily be rendered as required. I'm currently using UIkit and CKEditor, but this can easily be changed to Bootstrap/Foundation etc. It keeps everything simple so that Processwire can do all the heavy lifting. Note: I am aware that there is the excellent comments module by Ryan, and also the Discussions module by Apeisa, but I needed something a little different for my current project, so I decided to have a bash myself. I am by no means on the same level of coding as the majority of members on here, so please be gentle I'd also like to thank Ryan personally for such an excellent framework. Any questions etc, please feel free to ask.2 points
-
All you have changed in the script looks good, but ... ;-) ... the only thing what doesn't seem right is your main template dams (what I have named rccdams). This must be used for the combining (normal) dam pages. It cannot be used for a Inputfield of type "Page". You need to have that main template dam (or even dams and dam, if you give the parent page of all your dams an own template too.) The main template you need to refer to in the script is the dam template. This is used for all your dam objects. It will hold all other fields in the edit screen for the maintainers of the data. All other fields mean: all InputfieldPage, all InputFieldText, all inputFieldInteger, all InputFieldDatetime that contains data belonging to a (single) dam. Templates and fields of type InputFieldPage for (type, owner, country, purpose) needs to be created manually, before running the import part. (This looks good in your script config) All fields other than that of type InputfieldPage will be created by the createFields Action of the importer script. You need to run this action first. (looks also good in your script config) All other things, e.g. if you want to use more / other fields of type InputfiledPage depends on you. You should look and play a bit with the starter profile I have provided earlier. It shows some purposes as categories and how to use them with a multiple categories InputfieldPage that can be added to single dams. Also there is a single category InputfieldPage to study and play with. In my example, I have used the FIW exmple you provided in an above post. So, if you now do not have this field, you also can specify some source-fieldnames that you don't want to use as single inputfields but first gather their data, and put it together in a way that it fits to the purpose filed I have build, or you change the purpose field to match other criterias. My purposes categories do not only have a title field but also a subtitle field. You can see all this in the site profile. It's easy! And, if you have ran the import and the resulting data isn't what you expected, you once can run the deleteImportedData action to clear it out, change the config or change fetching and preparing the data of that particular part(s). And finally run the importer again. Good luck.2 points
-
And it is certainly worth exploring not only from developer point of view. Decent argument is so rare nowadays. Thanks for the share, diogo.2 points
-
Thanks! DIRECTORY_SEPARATOR was indeed unnecessary, I guess it was a victim of a copy-paste operation Unfortunately there were other bugs to fix. Just realized there are ajax-loaded FIELDS too and not only tabs. Now these are covered too (v0.85). Positioning of the links was improved too, and fixed the issue when the field had description or notes. Later I'll add enabled_templates function to make it more versatile, plus make field value clickable if the field is set to "closed + locked". If I knew there are so many field options to take into account I probably won't start this module2 points
-
I do not think that there is (or is needed) an IDE specifically for PW. But there are ways to make some IDEs work better with PW (autocomplete and so). Try reading through these threads: 1) https://processwire.com/talk/topic/3336-pre-release-templatestubs-ide-support-for-page-objects/ 2) https://processwire.com/talk/topic/10747-phpstorm-autocompletion-and-typehinting-of-wirexx/ 3) https://processwire.com/talk/topic/2770-recommend-a-code-editor-with-ftp-for-working-on-template-files/ 4) https://processwire.com/talk/topic/3518-what-ide-do-you-utilize/ 5) https://processwire.com/talk/topic/7427-pw-api-as-autocomplete-in-your-ide/ 6) https://processwire.com/talk/topic/1498-better-phpdoc-comments-in-pw-classes/2 points
-
It's a syntax error. // This is without the syntax error (note the dots and the single quotes) echo "<a class='link prev' href='" . $page->prev->url . "'>"; BTW: // Potential memory hog $pages->get(1019)->children->first() // This doesn't need to preload all children. The property boolean `true` is to count only the visible. $pages->get(1019)->numChildren(true)2 points
-
Hi Tony, I have attached a site-profile as example. It has some data in it that was populated with the following importer script. In the site profile I have created the dam_type and the dam_purpose categories and page fields. The dam_purpose was created as Multiple categories and there will be no items added automaticaly during import. The dam_type will be added automaticaly during install. there is only the templates and the parent created manually. Inspect the profile and look through the importer script, it has all needed comments. After playing around with it, I'm sure you can adapt it to suite your needs. site-rccdams-starter.zip save this besides your PW index.php and call it after you have logged in as superuser: <?php $GLOBALS['templateName'] = 'rccdams'; // the name of the template you use $GLOBALS['oldrccid'] = 'rccid'; // the fieldname in PW which stores the id from the source DB $GLOBALS['parentPath'] = '/rcc_dams/'; // add the path you want the pages stored, e.g. "/rccdams/" or that like, but check that you already have created this (parent) page in PW!! // the templates and parent pages for the categories needs to be created manually before the import action is used!! // also don't forgett to assign them to the rccdams template !! $categoryPages = array( 'dam_type' => array( 'nameOfParentTemplate' => 'dam_type_category_parent', 'nameOfChildTemplate' => 'dam_type_category' ), 'dam_owner' => array( 'nameOfParentTemplate' => '', 'nameOfChildTemplate' => '' ), 'dam_country' => array( 'nameOfParentTemplate' => '', 'nameOfChildTemplate' => '' ), 'dam_purpose' => array( 'nameOfParentTemplate' => 'dam_purpose_category_parent', 'nameOfChildTemplate' => 'dam_purpose_category' ) ); # # ATTENTION: SELECT AN ACTION HERE !! # # select an action you want to proceed by comment uncomment the following two lines # $ACTION = 'deleteImportedPages'; #$ACTION = 'createFields'; #$ACTION = 'importData'; // provide the credentials to connect to the Source-DB, including DB name and Table name $MYSQL = array(); $MYSQL['host'] = '127.0.0.1'; $MYSQL['user'] = ''; $MYSQL['pass'] = ''; $MYSQL['dbname'] = 'rccdams_db'; $MYSQL['tablename'] = 'rccdams_db'; // a list with all the fields and the their types, you want create / import into PW $rccdams_fields = array( 'dam_type' => 'Page', 'dam_country' => 'Page', 'dam_owner' => 'Page', 'dam_purpose' => 'Page', 'rccid' => 'Integer', 'dam_name' => 'Text', 'river' => 'Text', 'capacity' => 'Text', 'cd_proj_start' => 'Datetime', 'cd_proj_start_d' => 'Integer', 'cd_proj_start_m' => 'Integer', 'cd_proj_start_y' => 'Integer', 'cd_rcc_start' => 'Datetime', 'cd_rcc_start_d' => 'Integer', 'cd_rcc_start_m' => 'Integer', 'cd_rcc_start_y' => 'Integer', 'cd_proj_fin' => 'Datetime', 'cd_proj_fin_d' => 'Integer', 'cd_proj_fin_m' => 'Integer', 'cd_proj_fin_y' => 'Integer', 'cd_rcc_fin' => 'Datetime', 'cd_rcc_fin_d' => 'Integer', 'cd_rcc_fin_m' => 'Integer', 'cd_rcc_fin_y' => 'Integer' ); // I'm not sure if all the _d, _m, _y fields are needed. Maybe you only need the 4 Datetime fields! // you can adapt the list to suite your needs ############### READY with config part ########################### $GLOBALS['categoryPages'] = $categoryPages; $timeLimit = (60 * 5); // give it a bit more time than the default 30 seconds $ignoreUserAbort = false; // prepare server for plaintext output if(function_exists('apache_setenv')) @apache_setenv('no-gzip', '1'); @ini_set('zlib.output_compression', 'Off'); @ini_set('output_buffering ', '0'); @ini_set('implicit_flush', '1'); @ob_implicit_flush(true); @ob_end_flush(); if(isset($_SERVER['HTTP_HOST'])) { header('Content-Type: text/plain'); } // Bootstrap ProcessWire require_once('./index.php'); // security check if the current user is a SuperUser, comment the next line out, if you run this script from CLI if (!wire('user')->isSuperuser()) die('ACCESS DENIED!'); ignore_user_abort($ignoreUserAbort); set_time_limit(intval($timeLimit)); // Assign API variables to make things a little easier $fields = wire("fields"); $templates = wire("templates"); $modules = wire("modules"); $sanitizer = wire("sanitizer"); $pages = wire("pages"); echo "\n$ACTION\n"; if ('deleteImportedPages' == $ACTION) { echo "\n"; // we drop all imported pages foreach($pages->find("template={$GLOBALS['templateName']},include=all") as $p) { echo " - now drop {$p->title}\n"; $p->delete(); } echo "\nREADY!\n"; exit(); } if ('createFields' == $ACTION) { echo "\n"; // (1) first get the rccdam template $t = $templates->$GLOBALS['templateName']; if (!$t) { $fg = new Fieldgroup(); $fg->add("title"); $fg->save(); $t = new Template(); $t->name = $GLOBALS['templateName']; $t->fieldgroup = $fg; $t->save(); } // (2) loop through the field list and create those that are missing foreach($rccdams_fields as $name => $type) { echo " - $name :: $type\n"; if ('page' == strtolower($type)) continue; // field of type Page, this need to be created manually $f = $fields->$name; if (!$fields->$name) { // create a new field $f = new Field(); $f->type = $modules->get("Fieldtype" . $type); $f->name = $name; $f->save(); echo " successfully created\n"; } // add it to the rccdam template $t->fieldgroup->add($f); $t->fieldgroup->save(); $t->save(); } echo "\nREADY!\n"; exit(); } if ('importData' == $ACTION) { echo "\n"; // (1) connect to Source-DB $MY_sql = mysql_connect($MYSQL['host'], $MYSQL['user'], $MYSQL['pass']); if($MY_sql) { echo "- connected with MySQL Server\n"; $MY_sql_db = mysql_select_db($MYSQL['dbname'], $MY_sql); if($MY_sql_db) { echo "- connected with source DB\n"; $MY_sql_result = mysql_query("SELECT * FROM {$MYSQL['tablename']}", $MY_sql); if (is_resource($MY_sql_result)) { echo "- found the Table\n\n"; $t = $templates->$GLOBALS['templateName']; while($row = mysql_fetch_array($MY_sql_result, MYSQL_ASSOC)) { // (2) process all records of source table echo " -- fetched row with id {$row['id']}\n"; if (!isValidImportRecord($row)) continue; // this one is already present in PW, so skip further processing // we have data for a new page echo " this one needs to be imported\n"; $p = new Page(); // create a new page and assign the minimum required params: template, parent and title! $p->template = $t; $p->parent = $pages->get($GLOBALS['parentPath']); $p->$GLOBALS['oldrccid'] = $row['id']; $p->title = $row['dam_name']; // now loop through all source data fields foreach($row as $fieldname => $data) { if (!isset($rccdams_fields[$fieldname])) continue; // skip source data fields that are not defined in the $rccdams_fields array!! if (!$t->fieldgroup->$fieldname) continue; // skip source data when there is no field in our template // check which type we need in PW for this if ('Page' != $rccdams_fields[$fieldname]) { // we can simply add the source data into the target field, but pass it once through the sanitizer or typecast it to integer $data = 'Integer' == $rccdams_fields[$fieldname] ? (int)$data : $sanitizer->text($data); $p->$fieldname = $data; } else { // we have a Pagefield, we need to act accordingly, // here in the starter script I only work with dam_type and dam_purpose // the other needs to be added by you, switch($fieldname) { case 'dam_type': // this must be a single category Page !! in Details Tab it must set to SIngle Page or empty NullPage !! // we want create child pages for this category automatically, therefore // we need to check if there is already a child page, fetch this or create a new one: $data = $sanitizer->text($data); $cp = getCategoryPage('dam_type', $data); $p->$fieldname = $cp; break; case 'dam_owner': break; case 'dam_country': break; case 'dam_purpose': // this is a Multi-Items-Category and it has shortcuts in the source DB $data = strtolower(trim($sanitizer->text($data))); $cpa = getCategoryPagesPurpose($data); $p->$fieldname = $cpa; break; } } } $p->save(); echo " saved into DB!\n\n"; } mysql_free_result($MY_sql_result); } } } mysql_close($MY_sql); echo "\nREADY!\n"; exit(); } function isValidImportRecord($row) { // we check for a page with the rccdams template and the original id, (what we have stored under rccid with every imported page) $page = wire('pages')->get("template={$GLOBALS['templateName']},{$GLOBALS['oldrccid']}={$row['id']}"); // if a $page with ID greater than zero is found, we already have this page imported and want to skip it here, therefor we retun false! return $page->id > 0 ? false : true; } function getCategoryPage($name, $data) { $nameOfParentTemplate = $GLOBALS['categoryPages'][$name]['nameOfParentTemplate']; $nameOfChildTemplate = $GLOBALS['categoryPages'][$name]['nameOfChildTemplate']; // if there is no data in the source record, we return a NullPage Object if (empty($data)) { $cp = new NullPage(); } else { // if we have this page already in PW, we return it $cp = wire('pages')->get("template={$nameOfChildTemplate},name=" . wire('sanitizer')->pageName($data)); if (0 == $cp->id) { // if it ins't already there, we create it $cp = new Page(); $cp->of(false); $cp->template = $nameOfChildTemplate; $cp->parent = wire('pages')->get("template={$nameOfParentTemplate}"); $cp->title = $data; $cp->save(); } } return $cp; } function getCategoryPagesPurpose($data) { $nameOfChildTemplate = $GLOBALS['categoryPages']['dam_purpose']['nameOfChildTemplate']; $cpa = new PageArray(); // create an empty PageArray if (empty($data)) return $cpa; // if we have no source data, return empty PageArray for($i = 0; $i < strlen($data); $i++) { // add category pages to the array $cp = wire('pages')->get("template={$nameOfChildTemplate},name={$data[$i]}"); $cpa->add($cp); } return $cpa; } EDIT: I added the $ACTION "deleteImportedPages" to the script, and a few more comments. Please use this from above and not this that ships in the ZIP archive.2 points
-
FieldtypeFontIconPicker Supported Icon Libraries FontAwesome 4.7.0 Uikit 3.0.34 IonicIcons 2.0.1 Cahangelog NOTE: Module store data without prefix, you need to add "prefix" when you want to show your icon on front-end, because some of front-end frameworks using font-awesome with different "prefix". Module will search site/modules/**/configs/IconPicker.*.php and site/templates/IconPicker.*.php paths for FieldtypeFontIconPicker config files. All config files need to return a PHP ARRAY like examples. Example config file : create your own icon set. File location is site/configs/IconPicker.example.php <?php namespace ProcessWire; /** * IconPicker : Custom Icons */ return [ "name" => "my-custom-icons", "title" => "My Custom Icon Set", "version" => "1.0.0", "styles" => array( wire("config")->urls->templates . "dist/css/my-custom-icons.css" ), "scripts" => array( wire("config")->urls->templates . "dist/js/my-custom-icons.js" ), "categorized" => true, "attributes" => array(), "icons" => array( "brand-icons" => array( "title" => "Brand Icons", "icons" => array( "google", "facebook", "twitter", "instagram" ) ), "flag-icons" => array( "title" => "Flag Icons", "icons" => array( "tr", "gb", "us", "it", "de", "nl", "fr" ) ) ) ]; Example config file : use existing and extend it. File location is site/configs/IconPicker.altivebir.php <?php namespace ProcessWire; /** * IconPicker : Existing & Extend */ $resource = include wire("config")->paths->siteModules . "FieldtypeFontIconPicker/configs/IconPicker.uikit.php"; $url = wire("config")->urls->templates . "dist"; $resource["scripts"] = array_merge($resource["scripts"], ["{$url}/js/Altivebir.Icon.min.js"]); $resource["icons"]["flag-icons"] = [ "title" => "Flag Icons", "icons" => array("tr", "en", "fr", "us", "it", "de") ]; $resource["icons"]["brand-icons"]["icons"] = array_merge($resource["icons"]["brand-icons"]["icons"], array( "altivebir" )); return $resource; After you add your custom config file, you will see your config file on library select box. Library Title (Location Folder Name). If your library categorized and if you have categorized icons set like uikit and fontawesome libraries, you will have category limitation options per icon field or leave it empty for allow all categories (default). Example : output if ($icon = $page->get("iconField")) { echo "<i class='prefix-{$icon}' />"; } MarkupFontIconPicker Usage // MarkupFontIconPicker::render(YourIconField=string, Options=array) echo MarkupFontIconPicker::render($page->YourIconField, [ 'prefix' => 'uk-icon-', // Icon class prefix, if you have different prefix, default is : "fa fa-" 'tag' => 'span', // Icon tag default is : "i" 'class' => 'fa-lg', // If you have extra cutom classes, for example : icons sizes, Array or Sting value 'style' => 'your custom styles if you have' // Array or String Value ]); Theme support Search support Category support1 point
-
wireshell 1.0.0 is out See Bea's post -------- Original post ----------- Now this one could be a rather long post about only an experimental niche tool, but maybe a helpful one for some, so stay with me Intention Do you guys know "Artisan" (Laravel) or "Drush" (Drupal)? If not: These are command line companions for said systems, and very useful for running certain (e.g. maintenance, installation) task quickly - without having to use the Admin Interface, first and foremost when dealing with local ProcessWire installations. And since it has a powerful API and an easy way of being bootstrapped into CLIs like this, I think such a tool has a certain potential in the PW universe. It's totally not the first approach of this kind. But: this one should be easily extendable - and is based on PHP (specifically: the Console component of the Symfony Framework). Every command is tidily wrapped in its own class, dependencies are clearly visible, and so on. ( Here was the outdated documentation. Please visit wireshell.pw for the current one )1 point
-
A ProcessWire Fieldtype storing files in a customized location, outside the web root. This module is primarily useful if you need to store sensitive data which should not be accessible directly from the web. Normally, ProcessWire stores all files under /site/assets/files. Direct URL access to these files can be restriced by setting $config->pagefileSecure = true. Still you need to make sure that your template permissions are setup correctly. If something goes wrong, those files could be accessed from outside. GitHub: https://github.com/wanze/FieldtypeSecureFile Modules Directory: http://modules.processwire.com/modules/fieldtype-secure-file/ How does it work? After installing this module, you can create a new field of type SecureFile. Enter your configuration under the "Details" section when editing the field: Storage Location Enter a path outside the web root where the files are stored. You need to create the directory manually. Also make sure that the user running the web server has write permission. Roles allowing to download a secure file Users with a role selected here are able to download the files if a download is requested via the API. Allow Download in Admin If checked, users having a role selected above can download the files when editing a page. I needed this functionality for a recent project, so I created this module and thought to share it, mabye this is useful for someone else Consider it beta, I'm using it on one site but I'm sure it could be improved here and there. Feel free to suggest additional features! Cheers1 point
-
InputfieldURLChecker This is a tiny module to add a URL check button to InputfieldURL. It's live, meaning that it opens what you just typed in, and visible only if the field is non-empty. It's as unobtrusive as can Modules directory GitHub It would be the best if something similar would be built-in to PW. There will be probably some tweaks and settings in the future. Suggestions welcome (even for module name).1 point
-
This is a new version of Yahoo! Weather module for ProcessWire, old version of the module can be found at this link. The module has been rewritten, new options have been added alongside with caching from the API (Yahoo! API allows 20.000 calls per hour when using free version, so it comes in handy if your site has a lot of page hits). I've also updated icons in the package (you can easily swap them with yours in module icons folder). You can grab the module from the Modules page or directly from Github link. Update 1.0.1 Yahoo changed their forecast API URL (http://xml.weather.yahoo.com/ instead http://weather. yahooapis.com/), tiny update in Github repo. How to use You can call the module in two different ways: This is a basic call that renders the module, use this if you want only one instance of the module shown with WOEID set in the module settings. <?php echo $modules->get('MarkupYahooWeather')->render(); ?> If you want to show multiple instances of the module, call it this way: <?php $weather = $modules->get('MarkupYahooWeather'); $weather->woeid = 12587912; // Decatur, USA echo $weather->render(); $weather->woeid = 44418; // London, United Kingdom echo $weather->render(); ?> Options This module has the following options: Yahoo! Weather WOEID WOEID (Where On Earth ID) is an unique identifier for each city, you can easily find WOEID by using this site: http://woeid.rosselliot.co.nz. Default = Zagreb Set Locale Sets PHP locale, needed for localized date display. Default = en_US.UTF-8 Set Encoding Converts international date names to right format. Default = ISO-8859-1 Date Format Sets desired date output, formatted with PHP strftime function. Default = %A, %d.%m.%Y. Cache Time Cache time in minutes, caches .xml file(s) retrieved from Yahoo! API and pulls the data locally. Default = 5 minutes Display temperature in Fahrenheit instead of Celsius? Show weather conditions in Celsius or Fahrenheit scale (temperature: C/F; wind speed: km/h, mph; sunrise and sunset: 24h, am/pm). Show 5 day forecast below current weather forecast? Shows extended 5 day forecast, if unchecked, only current weather will be shown. Default = Checked Show wind direction and speed? Shows wind direction and speed. Default = Checked Show sunrise and sunset time? Shows sunrise and sunset time. Default = Checked Autoload script and stylesheet? Renders script and stylesheet during page render, if you prefer to include them manually, turn this option off. Default = Checked Load script in the bottom of the page? If "Autoload script and stylesheet" option is checked, you can select where script should be rendered automatically, before the end of head or body tag. Default = Unchecked Delete Weather Cache Deletes locally stored and cached .xml file(s) from Yahoo! API for all instances of the module.1 point
-
On mobile, therefore only the link: https://processwire.com/talk/topic/9730-get-pages-used-by-a-pagefield/#entry977051 point
-
Definitely going to keep my eye on this - fantastic idea! One of my current issues with file uploads is that they expose a certain directory structure. As much as PW is protected from that, I prefer file URIs to be a little more 'process' oriented - hence one of the reasons I created little Dispo. (Speaking of Pages as records, I've been meaning to discuss the possible storage-switch from DB to Pages for Jumplinks when I rewrite... Perhaps that would make it a lot more flexible...)1 point
-
1 point
-
Bernhard is right about that ID. When somebody deletes that page your code is broken. Another thing: // needs to load all children $pages->get(1019)->children->first() // better $pages->get(1019)->child1 point
-
To select/ provide any data of any table in your database which does not belong to processwire use module FieldtypeSelectExtOption. No need to import or transform data in a processwire format.1 point
-
Hello! It was solved at GitHub: https://github.com/ryancramerdesign/ProcessWire/issues/14161 point
-
No not *. If as custom code for a page select you need to use role id.1 point
-
Hi, a very useful Modul(ette). Primarily, it is not the "amount" of code what tells about the "weight" of a module. ------ BTW, when having a look at Github, I spotted DIRECTORY_SEPARATOR in URLs for script and style loading. Shouldn't it be a simple / (slash) instead?1 point
-
Thank you so much everyone! My gallery looks so much better already http://watanabe-yakushima.com/gallerie/ I just have to figure out how to add the descriptions of the images. That's not working yet1 point
-
Thanks for the offer, however I don't feel that HBB warrants any sort of payment as it is essentially a simple module. I will indeed give access to the code shortly. I'm not sure if it'll dissapoint, but I'll let you be the judge of that. I am interested in finding out what features people would like included. I'm keeping it as simple as possible, but so far there are fields to store the following information: Author's IP address & user agent string Topic / comment message content Creation / edit date (if edited) Pinned status Locked status Who has viewed the topic Which members can view the topic (ideal for private messages) The $page ID of the comment for reply status reference I'm toying with the idea to add fields for images and attachments, thus allowing the option to store images or attachments with comments, a bit like you can do with this forum.1 point
-
Your current code wouldn't be massively scalable as you're iterating every single page regardless of whether it has been previously processed or not. Your additional check you just mentioned - yes, you could (and probably should) do that with a longer selector, but I'm not sure what it's actually doing (is there a field for every language? Not sure what status$lang is doing). The extra field with the 1 in it after saving a page you've processed would mean the loop skips loading those pages that have already been processed next time you run it. I suggested the field with the 1 in purely as a quick example. The extra field wouldn't add much overhead as it's only used during this process (fields aren't pulled from the database when viewing a page unless you use them somewhere in your templates) but yes, there are other ways to do this too. If it is only to be run after every time you import large numbers of pages, you could also just jot down the last page ID and put ", id>14950" for example at the end of your selector. Lots of options1 point
-
It's still a modulette compared to other heavyweight modules The first post contains the link to the GitHub page (v0.8). There was a small code optimization but otherwise it's the same as v0.7.1 point
-
for reference: TagReplacer can do it https://processwire.com/talk/topic/11208-inputfieldtagreplacer/1 point
-
@ngrmm: take a closer look at the code Martijn posted and note the semicolon. Looks like your code is still missing that. While developing a site, you should run it in debug mode. This will output errors on screen and make it a lot easier to spot the source of issues like these.1 point
-
Deciding to use them for projects that don't need them isn't the greatest idea, to be honest. But, for learning purposes, I would give it a try. Should you choose to do so, you could also create yourself a blueprint of sorts for use in future projects. So no, you're definitely not being lazy - if the tools are not needed, then don't use them.1 point
-
Sometimes I feel horrible that I'm not using the cool kids tools, but truth be told I think none of my projects are that complex to really need this setup. Am I being lazy here? Should I actually try this tools to actually see the possible benefits? I mean, I do want to become a better webdev, just really haven't seen the need, I just feel that all that minification and optimized workflow works for complex stuff and when that time comes, I will make my move, meanwhile it feels like an overkill.1 point
-
Hey OviS, Sorry to hear you are running into this weird issue. I hadn't noticed the thread before, otherwise I would've responded earlier. At my previous company we had exactly the same issue. I never could really reproduce it. But when we migrated our servers the issue went away. We came from a rather old MySQL version (5.0.x.x) to a new one (5.6.x.x). I didn't noticed at once because we were using a temporary solution. We created a repeater with an Image field and a Text field per row. In the Image field setting we set the row to 0 so the description didn't show. Not really nice, but workable and our clients didn't really bother after a while. After the migration I did some work for a smaller client with images. I tried to see if the issue had been resolved. After a few edits and some time, it kept working. We took the plunge and converted them all back. No problems since. I don't know your setup and the way you guys work, but I would say a full site convert seems a lot more work then to create a temporary workable solution. Also you could try to reproduce with another MySQL version.1 point
-
Have you tried tweaking php settings, eg. max_input_vars? See for example https://processwire.com/talk/topic/8345-deleting-large-number-of-images-silently-fails/1 point
-
SimpleForms Alpha bumped to 0.8.0, featuring support for YAML configuration (proudly powered by symfony/yaml), in addition to JSON. You can now use a config.yaml file instead of config.json. Note that that JSON is preferred over YAML in the case that both files exist. An example YAML config file is in the default-forms directory. As you just noticed, the form directory is no longer named "forms" - it is now named "default-forms". When you install the module, the contents of this directory is copied to site/assets/forms. To me, this seems to be best-practice, considering the fact that the previous directory was wiped out on module upgrade. Lastly, you may find that, in some situations, selected fields need to be disabled when the form is rendered. For example, a "subject" field may need to be pre-populated based on a GET parameter and, therefor, read only. Often, the readonly attribute is enough, but I think disabled is better. Previously, such a field would be re-enabled after the form was processed and validation errors occurred (you may have noticed that the entire form is disabled when the form is processing). Now, these state of these fields persist by adding data-sf-disabled when the form is prepared by the front-end plugin. This makes the behaviour consistent with the intention.1 point
-
please take photos with the PW t shirt!! I wish you an awesome experience there!1 point
-
Is there any way I can send you money? (On some occasions I believe I have threatened to send money to someone brave enough to take a stab at creating a PW-based forum solution)1 point
-
There is one thing that needs a bit attention when importing data. We need to check if a record was also imported by a previous run of the script, otherwise you may end up with numerous duplicates. while($row = $result->fetch_assoc()) { $title = wire("sanitizer")->text($row['title'], array("maxLength"=>128)); // fetch and sanitize the title $p = wire('pages')->get("title={$title}"); // check if it already exists if(0 < $p->id) continue; // move on to the next record if it exists $p = new Page(); $p->template = "dam"; $p->parent = "something"; $p->title = $title; // use the sanitized title $p->save(); }1 point
-
I guess $myDB could be anything else. And that Database() is like Page(), something related to ProcessWire. But I could be wrong .1 point
-
Here's mine: site/assets/cache site/assets/sessions site/assets/logs site/assets/files site/config-dev.php1 point
-
Sounds interesting. Here's one way you can do it: $table = $fields->get('your_page_field')->getTable(); $query = $database->query("SELECT data FROM $table GROUP BY data"); $ids = $query->fetchAll(PDO::FETCH_COLUMN); $items = $pages->getById($ids); // $items is a PageArray echo $items->implode("\n", "<a href='{url}'>{title}</a>"); If we were to add this to the API, I think I'd want to make it accessible from a regular find() selector, rather than as a separate findSelectedPages method. That way it could be used with things like InputfieldSelector. Perhaps something like this: $pages->find("your_page_field=:selected"); ...where ":selected" is a keyword is would recognize to execute this behavior.1 point
-
And here's some code for those that may need it: $myfieldset_start = false; foreach ($page->template->fields as $field) { // or something like $this->templates->get('templatename')->fields if ($field->name == 'myfield') { // opening element of a fieldset is just the field name you gave it $myfieldset_start = true; } elseif ($field->name == 'myfield_END') { // ending element is field name with _END on it - break out of the loop if we reach this break; } elseif ($myfieldset_start == 'true') { // otherwise we are iterating fields in the chosen fieldset so do what you like here echo $field . "<br>"; } }1 point
-
I created Module with last dev version. Let me check for last stable version and i can see what is problem for oldest versions. Edit: Problem solved can you confirm after update to v0.0.51 point
-
1 point
-
Perhaps not the most elegant solution, but this seems to work: (make sure to choose "none" from the formatting options in your date-field) $d = $pages->find("template='basic-page',datum>0"); foreach($d as $dat) { $wd = date('w', $dat->datum); // weekday, 0 - 6 = Sunday to Saturday if($wd == 6) { $output .= "<p>Unformatted date: {$dat->datum} / Page: <a href='{$dat->url}'>{$dat->title}</a></p>"; } }1 point
-
Well said, because soon you won't like it a lot anymore. You will love it1 point
-
Ok I thought there maybe a way to construct PageArray's. You can't alter the children built in property I think as it is in fact a method to retrieve the children from the DB on runtime using selectors $page->children($selector), but you could add a custom value on runtime memory and make it another PageArray. Then add some children to it. Since you can't use "children" just have to name it different for example "mychildren" and it works. You can also then use all the PageArray methods on them as ususal. You will just have still the children() and parent(), siblings() etc available but they would be in the original context of where the page originally is and not in your pseudo PageArray. Here's a test script might useful for many others too. // note just simple test pseudo code // base array object $pa = new PageArray(); // get some pages to work with $category = $pages->get("/templates/"); $about = $pages->get("/about/"); $home = $pages->get("/"); // add new PageArray property "mychildren" $category->mychildren = new PageArray(); // add other pages in $category->mychildren->add($about); $category->mychildren->add($home); // you can sort them $category->mychildren->sort("-created"); // add the $category to the base array $pa->add($category); // output the nested PageArray using mychildren echo "<ul>"; foreach($pa as $p){ echo "<li><a href='$p->url'>$p->title</a>"; echo "<ul>"; foreach($p->mychildren as $child){ echo "<li><a href='$child->url'>$child->title</a></li>"; } echo "</ul>"; } echo "</li></ul>"; Gives a nested list: Templates About 2 Home1 point
-
1 point