Leaderboard
Popular Content
Showing content with the highest reputation on 04/17/2016 in all areas
-
I think most of us are "bushies"5 points
-
Love the new panel thingy! Especially the 'side effect' that you can use it as some sort mediaquery tester while dragging the pane .4 points
-
The simplest answer is that classnames cannot be shortened, but namespaces can. The ProcessWire namespace is not the best example here, because it's still not to long, therefore I'll use some namespaces from the flysystem package. use Aws\S3\S3Client; use League\Flysystem\AwsS3v3\AwsS3Adapter; use League\Flysystem\Filesystem; $client = S3Client::factory($credentials); $adapter = new AwsS3Adapter($client, 'your-bucket-name', 'optional-prefix'); $filesystem = new Filesystem($adapter); […] if(!$filesystem instanceof Filesystem) die(); // vs. $client = Aws\S3\S3Client::factory($credentials); $adapter = new League\Flysystem\AwsS3v3\AwsS3Adapter($client, 'your-bucket-name', 'optional-prefix'); $filesystem = new League\Flysystem\Filesystem($adapter); […] if(!$filesystem instanceof League\Flysystem\Filesystem) die(); Now imagine you'd need to use these classes 15 times in a file. You'd have to write them 15 times in their full glory without namespaces. With them you can always use the shortname of a class in your code, which keeps it readable and even if the shortname would collide you can do this to use an alternative short name for one of those in the file. (Alternativ naming does even work if classes don't clash.) <?php namespace kobrakai; use ProcessWire\User as PwUser; class User extends PwUser {} The use statement is super useful because you hardly need conflicting classes in a single file. Therefore you declare once which class you want to use in a file and never care about it later on. With longer classnames you need to constantly care about it trying to remember that one special long class name. The next benefit is the "folder" structure namespaces give yourself. As long as classes are in the same namespace you don't actually need to do anything besides the namespace declaration once. Only accessing classes outside the current namespace does need you to specify the namespace in any way. > kobrakai > Form > ImageGallery > … <?php namespace kobrakai; use DateTime; use ProcessWire\PageArray; class Form { public function ImageGalleryButtons(PageArray $options) { // Namespace needed $g = new ImageGallery(); // No namespace needed […] $date = new DateTime(); // DateTime is a core class, therefore also another namespace (root) } } Like you've seen above namespaces are great to extend classes. If I want to change a already existing file, which does use ProcessWire\User to use my own implementations (with maybe some additional business logic) I just change the use statement and I'm done. The file is still as readable as before. There were 100% no accidents in trying to search/replace classnames. We are still talking about users. <?php use kobrakai\User; // from: use ProcessWire\User; $u = new User; $u->name = 'my-user'; … if($another_u instance of User) $u->friend->add($another_u); …4 points
-
what Jan said, you can define sitewide $config options. Have a look into wire/config.php and copy the part of $config->imageSizerOptions into site/config.php if you want to change something. For example, if you want to have the "upscaling" disabled sitewide, just set it to false in your site/config.php. If you want to have a different value for an option then set in config.php, you can pass a options array with the image resize functions: $options = array("upscaling" => false, "sharpening" => "medium"); $image->width( $width, $options ); $image->height( $height, $options ); $image->size( $width, $height, $options );4 points
-
This module is deprecated in favor of RockMigrations. It'll continue to work and I might fix some smaller incompatibilities if they're reported, but no major development will happen on this anymore. There where various threads about a how to reasonably handle multiple dev/staging and live environments with ProcessWire and at best handle it as automatically as possible. A git based workflow makes it easy to handle files, but the pain point of migrating db changes has even lead to multiple requests of not handling template/field storage in the db at all. I've gone ahead and used for my own projects the concept of database migrations, which most frameworks are using to handle database changes – but the ProcessWire flavored way. ___ ___ ___ ___ ___ ___ ___ /\__\ /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ /::L_L_ _\:\ \ /::\ \ /::\ \ /::\ \ \:\ \ /::\ \ /:/L:\__\ /\/::\__\ /:/\:\__\ /::\:\__\ /::\:\__\ /::\__\ /::\:\__\ \/_/:/ / \::/\/__/ \:\:\/__/ \;:::/ / \/\::/ / /:/\/__/ \:\:\/ / /:/ / \:\__\ \::/ / |:\/__/ /:/ / \/__/ \:\/ / \/__/ \/__/ \/__/ \|__| \/__/ \/__/ Beta This module does help you managing migration files, where any database changes can be stored in php files using just the simple ProcessWire api at your disposal. It's not as nice as using the admin UI, but certainly better than trying to migrate changes manually and possibly weeks after adding the changes. Also there's always the option to create helper modules, which can export changes made in the admin UI to something usable in those migration files. For example I'm using an internal process module, which does let me export changes to template access rules as json strings, which I then use in my migrations to actually apply the changes. Now on to the meat – How to use the module: Read the following guide on creating own migrations Maybe use the CLI tool to speed up your workflow (and possibly automate stuff) It is generally recommended, but not enforced, that migrations are run/rolled back in order. When doing migrations or rollbacks, without specifying a migration, this module will stick to the order. Creating Migrations Your migrations will probably hold lot's of code, which does delete data. By now this module does not have any security measurements to prevent that. Be sure to test your migrations locally and possibly keep a database backup before running them. There are currently four types of migrations: default (Migration) Default migrations are the most free form migrations. There's just a description and two functions – update() and downgrade(). What you're doing in those functions is totally up to you, but it's recommended to try the best to keep changes as reversible as possible. Meaning that running update() and downgrade() once should have as less effect on the installation as possible. The ProcessWire API is available exactly like in modules using the $this->pages, $this->config, … syntax. FieldMigration TemplateMigration ModuleMigration All of those are there to make your life easier. They all have different but similar functions – which you can find in migrations created by this module – which ease the creation and removal of fields, templates or modules. All the boilerplate is handled by the base classes these migrations do extend, so you don't even need to think about update() and downgrade(). You can rather just describe the item you want to handle and the creation / removal process is taken care of. These are by now not highly tested, so please again be sure to test migrations before running them on important content. Command-Line Interface The module does include a cli interface, which does allow the migrations to be run automatically by CI or deployment scripts or just by you if you like cli's. The cli script is located in the bin directory inside the module's folder. It does however require a composer package to work, which you can simply add by running composer require league/climate in your site directory (or the root directory for pw 3.0). Make sure to require composers autoload.php in your config.php for 2.x installations. The CLI does have a quite handy help page, which you get by running php migrate -h so I'm just adding the important bits of that here: > php migrate -h […] Usage: migrate [-h, --help] [-i info, --info info] [-m migrate, --migrate migrate] [-n new, --new new] [-nf newField, --newField newField] [-nm newModule, --newModule newModule] [-nt newTemplate, --newTemplate newTemplate] [-r rollback, --rollback rollback] Optional Arguments: -m migrate, --migrate migrate Run a specific migration or all new* ones if none given. * From latest migrated to newest. -r rollback, --rollback rollback Undo a specific migration or the latest one if none given. -n new, --new new Bootstrap a new migrations file. Optionally you can already supply a description. -nt newTemplate, --newTemplate newTemplate Bootstrap a new template migrations file. Optionally you can already supply a description. -nm newModule, --newModule newModule Bootstrap a new module migrations file. Optionally you can already supply a description. -nf newField, --newField newField Bootstrap a new field migrations file. Optionally you can already supply a description. -i info, --info info Get detailed info about a migration. -h, --help Show all commands of the cli tool. Link the migrations cli update save to ProcessWire's root: https://processwire.com/talk/topic/13045-migrations/?p=118329 Helper Functions There are already a handful of helper function included in the Migration base class, which tackle things I found to need way to much boilerplate for kinda simple changes, but you can also add own custom helper functions via hooks. /** * This does use @diogo's while loop technique to loop over all pages * without getting memory exhaustion. */ $this->eachPageUncache("template=toBeHidden", function($p){ $p->setAndSave('status', Page::statusHidden); }); /** * $template, $field, $reference = null, $after = true * The below function reads like this: * In the template … add the field … relative to the field … in the position after/before */ $this->insertIntoTemplate('basic-page', 'images', 'body', false); /** * Edit field settings in context of a template */ $this->editInTemplateContext('basic-page', 'title', function($f, $template){ $f->label = 'Headline'; }); And a simple example of adding a custom helper as a hook. // in ready.php $wire->addHook('Migration::renameHome', function(HookEvent $event){ $name = $event->arguments(0); wire('pages')->get('/')->setAndSave('title', $name); }); // in the migration $this->renameHome('Root'); Snippets Still not sure how all this works in practice? Or you want to share a maybe more complex migration? Just head over to the Snippets Repo at Github. https://github.com/LostKobrakai/MigrationSnippets There are also less specific examples in the modules repository: https://github.com/LostKobrakai/Migrations/tree/master/migrations Appendix As long as the module is in Beta the helper functions in the Migration.php might be object to change/removal, so be aware of that. Download http://mods.pw/Bm https://github.com/LostKobrakai/Migrations3 points
-
ClearCacheAdmin Module Since there's so many asking how to clear cache. Here comes a helper module that let's you clear caches directly from the admin menu. Additionally it has its own admin page that's a collection of the various caches available in ProcessWire in one place. See some infos and clear them. WireCache (using $cache) caches in the DB and there no way to clear it from the admin. Now you can delete the entries individually or all in one go. Supports following cache types: - Template "Page" Cache (disk file cache) - MarkupCache module (file cache) - WireCache (DB) - Other files and directories found in assets/cache/ path Wanted to do this for a long time. It was also great fun to do it and give something to the community to also learn something. For now it's on github only. Requires ProcessWire 2.6+. https://github.com/somatonic/ClearCacheAdmin3 points
-
hi robin, as simple as this: (put it in your /site/ready.php file and adjust to your needs) $this->pages->addHookAfter('added', function($event) { $page = $event->arguments[0]; if($page->template != 'your-template-name') return; $page->setAndSave('title', 'my page - ' . date("YmdHis")); }); set page name format for children to something like Y/m/d H:i:s and set title to locked3 points
-
3 points
-
In my case, it's only been worth the effort for one site that I deal with that is doing constant imports all day. It makes a difference in the performance of other requests there. There are a lot of technical benefits to InnoDB relative to MyISAM for sure. But in the PW context (or most CMS contexts) it's hard to derive much value from those benefits until you run into specific needs or scale. In 15+ years and thousands of MyISAM tables around here, I've never experienced any kind of data corruption or loss associated with MyISAM tables. If starting something new I think InnoDB is worthwhile if it can be supported in your environment, but for most cases of existing PW installations I don't think it's worth the effort unless the circumstances mentioned in post are present. From what I understand, MyISAM's fulltext indexes may still be stronger than InnoDB's, though not positive that's still the case. Btw, PW will use InnoDB either way for cases where it makes the most difference.3 points
-
You can alter an existing table simply by issuing ALTER TABLE your-table-name ENGINE=InnoDB; Though you may want to keep the original MyISAM table around. Here's a small bootstrap script to drop into the templates folder that converts all tables, either inplace (if $keepOld near the top is set to false) or creating a copy and keeping the MyISAM tables around postfixed with "_orig". It also writes a timestamped SQL file into the templates folder that allows you to switch back to MyISAM. Small caveat: if you select to keep your old tables, those will replace the generated InnoDB tables on restore, which means that all PW changes in between are lost - this may or may not be desired. So to use it, simply drop it in the templates folder of the PW installation in question and run it from the command line. It will check if you MySQL version is recent enough. <?php /** * Convert all tables in PW's database from MyISAM to InnoDB */ include('../../index.php'); // Set this to false if you do not want to keep your MyISAM tables around // with an _orig postfix $keepOld = true; // ***************************************************************************** $sql = "select substring(version(), 1, 1) as vmajor, substring(version(), 3, 1) as vminor "; $stmt = $database->query($sql); if($stmt === false) die("Something went wrong determining the version number!"); $row = $stmt->fetch(PDO::FETCH_ASSOC); $versionOK = false; if($row['vmajor'] > 5 || ($row['vmajor'] == 5 && $row['vminor'] >= 6)) $versionOK = true; if(!$versionOK) { die("You need MySQL 5.6 or later for InnoDB fulltext support!"); } // Version check finished, get list of tables $stmt = $database->prepare( "SELECT table_name" . " FROM information_schema.tables" . " WHERE table_schema = '" . $config->dbName . "'" . " AND lower(engine) != 'innodb'" ); $count = 0; if($stmt->execute()) { $tbls = $stmt->fetchAll(PDO::FETCH_ASSOC); echo "Found " . count($tbls) . " tables not running on InnoDB" . PHP_EOL; if(count($tbls) == 0) { echo "Nothing to do!" . PHP_EOL; exit; } $ts = strftime("%Y%m%d_%H%M%S"); $restore = fopen("restore_to_myisam_{$ts}.sql", "w+"); echo "- writing restore commands to file restore_to_myisam_{$ts}.sql" . PHP_EOL; // Convert each table foreach($tbls as $tbl) { $tabname = $tbl['table_name']; echo $tabname . PHP_EOL; if($keepOld) { // Create a copy of each table, convert the new table, // copy the content and switch table names $sql = "CREATE TABLE {$tabname}_convert LIKE $tabname"; if($database->exec($sql) === false) continue; echo "... Created copy of " . $tabname . PHP_EOL; $sql = "ALTER TABLE {$tabname}_convert ENGINE=InnoDB"; if($database->exec($sql) === false) continue; echo "... Changed engine to InnoDB" . PHP_EOL; $sql = "INSERT INTO {$tabname}_convert SELECT * FROM $tabname"; if($database->exec($sql) === false) continue; echo "... Copied content to InnoDB table" . PHP_EOL; $sql = "RENAME TABLE $tabname TO {$tabname}_orig," . " {$tabname}_convert TO $tabname"; if($database->exec($sql) === false) continue; echo "... Switched tables" . PHP_EOL; fputs($restore, "RENAME TABLE $tabname TO {$tabname}_innodb," . " {$tabname}_orig TO $tabname;" . PHP_EOL); fputs($restore, "DROP TABLE {$tabname}_innodb;" . PHP_EOL); $count++; } else { // Convert tables in place $sql = "ALTER TABLE $tabname ENGINE=InnoDB"; if($database->exec($sql) === false) continue; echo "... " . $tabname . " converted" . PHP_EOL; fputs($restore, "ALTER TABLE $tabname ENGINE=MyISAM;" . PHP_EOL); $count++; } } fclose($restore); } echo "Converted $count tables from MyISAM to InnoDB" . PHP_EOL; Edit: incorporated @LostKobrakai's suggestion to avoid nesting if statements.3 points
-
if(count($page->images)) { $images = ''; foreach($page->images as $image) { if($image->width < 801) { $image = $image; } else { $image = $image->width(800); } $images .= "<img src='{$image->url}' /><br />"; } }3 points
-
Even easier, if you install the Upgrades + Upgrades Checker modules in order to perform the upgrade with a few clicks (while reading the inline instructions carefully...)2 points
-
If the filesystem is not writeable, no one and nothing can do anything. I suggest the same as @Kongondo. Grab you a ZIP of your desired branch (devns I assume), copy it to your server (local or online), make sure, at least your site/assets/{ALL_SUBFOLDERS} are writeable by the php-user. Then run the installer. If you later on want to install a newer devns version, you have nothing more to do then to change the complete wire folder. For example, if you have PW 3.0.15 now, rename your wire folder to wire.3015, copy/upload the wire folder of PW version 3.0.17 to your installation and login into the admin. That's it. Easy. And yes: - Welcome to the forums.2 points
-
Except when you introduce yourself to potential client and you must quickly transform into a professional (But that's off topic again, sorry for that...)2 points
-
Not wanting to rain on your parade, but seeing that you are missing out on all the fun of playing with ProcessWire, I'd suggest that for starters you install ProcessWire the 'normal' way. Download a zip file and copy that to your server, unzip it, call that location in your browser and click through . Alternatively, get @Soma's online installer thingy (you can edit it to grab the version of PW you want) and it will do the downloading for you plus start the installation. Totally painless. Later on, if you are still up to it, you can play around with deploying via git ... Just my 2p Edit: Oops. welcome to the forums! (where's my manners, tsk, tsk)2 points
-
I think that should be $content.= $map->render($items, 'contact_gps'); (without " ")2 points
-
Probably best to point out (to new users) that setAndSave() is a recent addition. Otherwise you might bet questions why is it not working for me?2 points
-
The File Compiler may still compile the file, but that doesn't mean it'll use it. It can compile a file for no purpose other than to determine if there would be any differences provided by compilation.2 points
-
You don’t need to call size() at all if you don’t want to resize the image. Also you don’t seem to be entirely familiar with PHP’s control flow syntax. Try this inside your foreach: if ($image->width <= 800) { //width is simply a property of type integer, in pixels $imgurl = $image->url; //use url of source image } else { $imgurl = $image->size(800)->url; //create a variation 800px wide and use its url } $images .= "<img src='{$imgurl}' />"; You may also be interested to know that there is a config option that prevents images from being upscaled. Have a look around in config.php’s image options. I don’t know if it’s some kind of special syntax you’re using for your if-condition, but here is the PHP manual just in case: http://php.net/manual/en/control-structures.if.php Sorry, I would format more nicely, but I’m on mobile :/2 points
-
Hi all, here's my first official module. I created it for a project I'm working on, so I thought I'd release it in case anyone else finds it useful. If you have any suggestions or find any issues with it etc, please post them here. NOTE: I have only tested it on PW 3.0.3, so you might want to try it on a test installation first if you decide to use it. Lumberjack Logger Module A simple module for ProcessWire CMS that logs the IP / User Agent details of the user when the page is saved. Installation Copy the Lumberjack folder to /site/modules and then refresh the modules from Admin->Modules. Lumberjack can then be installed. Usage Two new fields will be created when Lumberjack is installed. lumb_ip_log - This field is used to store the IP lumb_ua_log - This field is used to store the User Agent String You can add both fields or just one to the required templates. Pages using those templates will then automatically store the IP and User Agent of the user when the page is saved. Settings Lumberjack can be disabled by unchecking the Enabled option on the settings page. Screenshot Download Link https://github.com/GuruMeditation02/Lumberjack Updates Version 0.1.1 - Added User Agent String santization2 points
-
-------------------------------------------------------------------------------------------------------------------------------- for PW 3.0+ please follow this link! -------------------------------------------------------------------------------------------------------------------------------- Croppable Image Module for PW >= 2.5.11 and PW <= 2.7.3 Version 0.8.3 alpha Hey, today I can announce an early (alpha) release of CroppableImage, what was forked from Anttis Thumbnails module. Until now there was a lot of work done by owzim, Martijn Geerts and me. We have solved the issues regarding the list from here: The modules are bundled together so that you only can and have to use FieldtypeCroppableImage for install, uninstall & configure. It uses new naming scheme that was introduced with PW 2.5.0 that supports suffixes. The complete image rendering is delegated to the core ImageSizer, or to any optional hooked in rendering engine. Template-settings are now fully supported, including removing variations when settings have changed. It fully respects settings for upscaling. If upscaling is set to false, you cannot select rectangles smaller than the crop setting. We implemented these enhancements: The GridView now is very nice and compact, and also benefits from the lately introduced setting for $config->adminThumbOptions. Permanent storage of the crop coordinates, quality and sharpening settings are now implemented native. No need to use PiM for this anymore. The usage/display of the Quality and Sharpening DropDown-Selects can be globally disabled/allowed in the modules Configpage. (additionally to that a setting on a 'per field base' is planned.) And the most wanted feature by the community: It gives back a pageimage and not the URL-string. This way you can use it like this: // get the first image instance of crop setting 'portrait' $image = $page->images->first()->getCrop('portrait'); You can further use every pageimage property like 'url', 'description', 'width' & 'height' with it: // get the first image instance of crop setting 'portrait' $image = $page->images->first()->getCrop('portrait'); echo "<img src='{$image->url}' alt='{$image->description}' />"; And you can proceed further image rendering with it: // get the first image instance of crop setting 'portrait' and proceed a resize with imagesizer $image = $page->images->first()->getCrop('portrait'); $thumb = $image->width(200); // or like this: $thumb = $page->images->first()->getCrop('portrait')->width(200); // and if you have installed Pia, you can use it here too: $thumb = $page->images->first()->getCrop('portrait')->crop("square=120"); The only downside with this is that when you (as the site developer) have enabled the usage of DropDown-Selects in the images editor, you do not know the values the editors have chosen for the images. As a workaround for this you can use the getCrop() method with a second param. This is a PW selector string. It can contain as many of the known pageimage options like 'quality', 'sharpening', 'cropping', etc, as you need, but none of them is required. But required is at least one setting for 'width' or 'height': $image = $page->images->first()->getCrop('portrait', "width=200"); $image = $page->images->first()->getCrop('portrait', "width=200, height=200, quality=80"); $image = $page->images->first()->getCrop('portrait', "height=400, sharpening=medium, quality=75"); . . You can get the module from GitHub: https://github.com/horst-n/CroppableImage (Better Docs are coming soon) Screenshots Related Infos A good setting in site/config.php for the AdminThumbs are: (height=>200 and scale=>0.5 !) $config->adminThumbOptions = array( 'width' => 0, 'height' => 200, 'scale' => 0.5, 'imageSizer' => array( 'upscaling' => false, 'cropping' => true, 'autoRotation' => true, 'sharpening' => 'soft', 'quality' => 90, 'suffix' => array(), ) );1 point
-
Don't need to copy anything manually (like site-default to site), the installer will do this for you. All you have to do is check out your desired branch and access the installer through http. It will take care of creating the neccessary file system structure.1 point
-
Are you talking about allowing the fieldset to show up when users visit their profile page? If you are, then try this; Log back in as superuser Edit the configuration for the core module ProcessProfile Select all your new fields, including the fieldset, by checking the box next to them Save the module settings Now log back in as a non-superuser and visit your profile page. Untested - YMMV1 point
-
@BitPoet Just a suggestion: Maybe inverting those if statements could make this a bit less nested. if($database->exec($sql) !== false){ […] } // to if($database->exec($sql) === false) continue; // or break;1 point
-
Yeah https://github.com/somatonic/ClearCacheAdmin/commit/88da90563991b7e156d0738143be7b17dc43249b I'm running php 5.3 and it works.1 point
-
@Ivan, Back in 2012, I decided to compare access times of a locally hosted site both before and after I switched it over to InnoDB. At the time I was in a dialog with Ryan about the benefits of, at least, allowing InnoDB as one of the DB engine choices during install. After all these years, I am delighted to see it finally arrive. Here's a screenshot of the side-by-side results of running 500 requests vs a, then standard, PW install - one using MyISAM and one using InnoDB. In general, MyISAM was faster than InnoDB - but it also had a larger standard deviation in the delivery times. Don't worry about the "failures" reported above - remember that the default install back then would serve one of a set of random images and the test tool looks to see which responses matched the first response - a non-match counts as a "failure". InnoDB did have a slightly higher throughput in terms of requests served per second.1 point
-
Just click the name and it's retrieving a fresh copy from github even for the same version number.1 point
-
Fantastic. Been waiting very long for something that takes me back to the days of Rails migrations! I will be doing a screencast on this in my WP vs. PW series. Just in time!1 point
-
Perhaps sanitise the user-agent string you pull from the $_SERVER variable? I don't know how much of a risk it really represents in this case, but it is possible to overwrite these headers with certain browser extensions, meaning they can be crafted by cunning minds, to supply certain strings to applications. At the very least I'd think about stripping tags from that value before you store it.1 point
-
1 point
-
@GuruMeditation Thank you for the module - and welcome to the wonderful world of "official" module authorship!1 point
-
1 point
-
Some of you may have read about it: there are a new core images field in the works for the PW 3 branch. I want to wait until this is released and then update the Croppableimages to sit upon that. I think it will become a new version for PW 3+ only, as there is the current version available for the PW 2 branch. Besides some PW 3 namespace issues there should be implemented changes to work with the new images field in that way, that it only enhances this with the cropbuttons but leave the other UI as is (reuse it). I'm not very good with this UI stuff, so, if I will not be able to do this myself, I will ask here for help on that. If this will be the case, I will provide an intermediate version that works with the PW3 and new image field first. Everyone who can't wait until then should use the slightly hacky upgrade procedure provided by @KentBrockmann and @noodles, two posts above this one.1 point
-
This is exactly what I needed to get image uploads working on my vagrant box (scotch.box). Edit: Had this problem on another vagrant box today, searched for the solution, and found this post—but I forgot where to find the php.ini file on scotch.box. So here are the baby steps, future self: Connect to the box shell: vagrant ssh Open php.ini in vim: sudo vim /etc/php5/apache2/php.ini Find the right line: /always_populate_raw_post_data<CR> Uncomment the line: 0x Save and quit: ZZ Restart Apache: sudo service apache2 restart Exit the vagrant shell: <C-d>1 point
-
Thanks for the suggestions. I just discovered addClass() while looking through the code in Inputfield.php. Unfortunately neither is working. The particular Inputfield I'm trying to work with is InputfieldPage. I'm wondering if the problem is that this is a sort of "hybrid" inputfield? It doesn't seem to use the attributes in its render() function at all, as far as I can tell. EDIT: I'm now trying to hook after InputfieldPage::getInputfield to see if that will work. Still no luck. public function init() { $this->addHookAfter('InputfieldPage::getInputfield', $this, 'hookAddCssClass'); } public function hookAddCssClass(HookEvent $event) { $inputfield = $event->return; $inputfield->addClass('myClassName'); $event->return = $inputfield; }1 point
-
Hey, I really spend a lot of time to figure out how to add additional options to a config page (which are generated with the function "getConfigInputfields"). I use an autoload module for this, At first we need to create the module: <?php class ExampleModule extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'ExampleModule', 'summary' => 'Bla bla', 'version' => 1, 'autoload' => true ); } // the rest of the code should be here } ?> Then we add the init function to it which includes a hook into the config page page we want to extend. In my case it is the option page of the InputfieldDatetime: public function init() { $this->addHook('InputfieldDatetime::getConfigInputfields', $this, 'addConfig'); } The last step is of course the "addConfig" function: public function addConfig(HookEvent $event) { // get the field instance used by the config form $field = $event->object; // TRICKY PART: use it's name to get it's saved values $data = $this->fields->get($field->name)->data; // add a new field with the saved value to the form $fields = $event->return; $field = $this->modules->get("InputfieldCheckbox"); $field->name = "useSimpleDate"; $field->label = "Use \"Simple Date\"?"; $field->checked = ((@$data['useSimpleDate']) ?: 0); $fields->add($field); // return the new config form $event->return = $fields; } The only really tricky part is to get the value. In this case it works like this. In other cases you may have to get the modules config.1 point
-
BTW: the intended way I think is to call size instead of width or height, but with disabled cropping: $image = $page->images->first(); $options = array('cropping'=>false); echo "<img src='{$image->size(900,900,$options)->url}' alt=''>";1 point
-
Okay, so here's what I came up with: Goal: Make a branch of pages in the Home tree completely hidden from a "client" role, say of Menus or Sidebars, but that is visible from a tab in the admin's primary menu so that the client is just dealing with pages in the "Home" tree. The end result being just "Pages," "Menus," and "Sidebars" in the primary admin menu. Steps: 1) I make a template called "node" for any parent page that starts a branch of pages that shouldn't be viewable in the Home tree to the client role. This isn't necessary but I feel like it's helpful because now these pages don't resemble the regular page template if the user somehow stumbles upon them. 2) I make a page called "Menus" and assign it the "node" template in the Home tree. All my custom menus are children of this page. 3) I make a page called "Menus" as a child of the hidden Admin page in the Home tree. This causes PW to make a tab with the message about not having a process assigned to it. 4) I make a module that assigns a process to the new template: (http://processwire.com/talk/topic/1272-new-page-nav-in-admin/): class UtilityMenuList extends Process { public static function getModuleInfo() { return array( 'title' => 'Custom Menu List', 'summary' => 'List all custom menus.', 'version' => 100, 'permission' => 'page-edit' ); } public function execute(){ $pl = $this->modules->get("ProcessPageList"); $pl->set('id',1057); // or any other parent page return $pl->execute(); } } Here we set the ID to the "Menus" page from step 2. This is the branch of pages we want to appear on the Menus tab. 5) We go back to the Menus admin page from step 4 and choose UtilityMenuList from the Process field. This makes PW show a Home tree that only includes the Menus branch. 6) Now we want to exclude the Menus branch from being visible on the Home tree, since that should only show "regular" Pages. I followed Soma's tutorial here for extracting branches from the JSON, since it's not apparent how to hook into ProcessPageList according to this thread: http://processwire.com/talk/topic/1272-new-page-nav-in-admin/. We create another module: <?php /** * Utility Hide Nodes * * Hides pages with a node template from display in the admin. * * ProcessWire 2.x * Copyright © 2010 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://www.processwire.com * http://www.ryancramer.com * */ class UtilityHideNodes extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Hide Node Pages', 'version' => 100, 'summary' => 'Example module to hide page in the admin per user per page. Add a page field "pagelist_hidden" with a PageListSelectMultiple input type to the user template. Select or add pages you want to hide in the admin.', 'href' => '', 'singular' => true, 'autoload' => true ); } public function init() { // only add hook only if the render parameter is set // (as used by ProcessPageList) if(!isset($_GET['render'])) return; $user = $this->user; $roles = $user->roles; // loop thru each role foreach($roles as $role) { if (!$role->pagelist_hidden) return; } $this->addHookAfter('ProcessPageList::execute', $this, 'pageListHiddenPages'); } public function pageListHiddenPages(HookEvent $event){ $user = $this->user; $roles = $user->roles; foreach($roles as $role) { foreach($role->pagelist_hidden as $hidden_page) { $hidden[] = $hidden_page->id; } } // make sure it's an ajax request if($this->config->ajax){ // manipulate the json returned and remove any pages found from array $json = json_decode($event->return, true); foreach($json['children'] as $key => $child){ if(in_array($child['id'],$hidden)) unset($json['children'][$key]); } $json['children'] = array_values($json['children']); $event->return = json_encode($json); } } } 7) I altered Soma's code to make it work with roles. We go to the Role template instead of User and add a new field called "pagelist_hidden" of the type Pages, with the following settings: Details = Multiple Pages (PageArray) and InputFieldType = PageListSelectMultiple. This will let us choose specific pages to make hidden from the Home tree on a role-by-role basis. 8) In my case I have a "client" role, so I assign this field to the Role template and then pick my Menus branch on the "client" role. 9) If I log in as the client role, the Menus branch doesn't appear at all in the Home tree, but I can still see it in the branch that gets outputted under my new Menu tab. So as a result we can add as many tabs as we need (potentially to create the illusion of more content types beyond pages) and hide as many branches thru the admin interface by simply adding them to the client's user role. The Menus parent page still appears on this tab, which is unfortunate but not so bad. If this were a Blog section, it would still make sense visually. I just set the parent to be uneditable, that way the client can't mess with it, but the children are still editable. Next step would be... can we somehow paginate a branch? Anyhoo it's pretty neat so far. Edit: Altered Soma's code to work with roles & not individual users.1 point