Leaderboard
Popular Content
Showing content with the highest reputation on 09/28/2013 in all areas
-
This is a very simple module that I put together for @Zahari Majini from a PM request. It allows you to enter a URL to a YouTube or Vimeo video in a specified field and when you save the page, it will grab thumbnails for the video and add them to a specified images field. Check the module configuration options for: the field(s) to search for videos name of the video images field which thumbnail(s) you want grabbed whether to grab the first available or all available thumbnails based on those that you list As always, an feedback for improvements is very welcome! Modules Directory: http://modules.processwire.com/modules/process-get-video-thumbs/ Github: https://github.com/adrianbj/GetVideoThumbs3 points
-
Hi Guys, I've decided to share my work on a Fieldtype for adding star ratings to page items. I used @apeisa's FieldtypePoll as a starting point. Check out the readme on github for usage: https://github.com/jdart/FieldTypeRate I've got a couple screenshots that should demonstrate the functionality. Feel free to give me any feedback. Regards, Jonathan2 points
-
Started a new module for creating <tables> from repeater fields. Feel free to grab it from github, do with it what you want. It only works for simple text based fields inside a repeater. To use it: $table = $modules->get("RepeaterTable"); // initialize $table->thead = true; // (bool) true/false, default = true, will render <th> $table->indent = 3; // (mixed) false/int, where int is the level of indentation, default: false $table = $table->render($page->repeater); // repeaterfield called repeater <!-- output --> <table class="table-repeater"> <thead> <tr> <th class="col-1">Fieldlabel field 1</th> <th class="col-2">Fieldlabel field 2</th> <th class="col-3">Fieldlabel field 3</th> </tr> </thead> <tbody> <tr class="row-1"> <td class="col-1">data for field 1, first repeater item</td> <td class="col-2">data for field 2, first repeater item</td> <td class="col-3">data for field 3, first repeater item</td> </tr> <tr class="row-2"> <td class="col-1">data for field 1, second repeater item</td> <td class="col-2">data for field 2, second repeater item</td> <td class="col-3">data for field 3, second repeater item</td> </tr> </tbody> </table> For the HTML purist, I have added source code indentation where you can set how many tabs you wish to append before each element. Please let me know if I should add this to the modules directory ? Does someone have a good name for this ?2 points
-
Ryan I just pushed a change to the inputMapMarker.js file on github that solves this problem. Added this inside the InputFieldMarker function: // added by diogo to solve the problem of maps not rendering correctly in hidden elements // trigger a resize on the map when either the tab button or the toggle field bar are pressed $(document).ready(function() { // get the tab element where this map is integrated $tab = $('#_' + $(map.b).closest('.InputfieldFieldsetTabOpen').attr('id')); // get the inputfield where this map is integrated and add the tab to the stack $inputFields = $(map.b).closest('.Inputfield').find('.InputfieldStateToggle').add($tab); $inputFields.on('click',function(){ // give it time to open window.setTimeout(function(){ google.maps.event.trigger(map,'resize'); }, 200); }); }); I had to put it inside the function, to have the "map" variable in scope. I'm not sure how we could move it outside the function if you don't like it that way. Also, the 200 value on the setTimeout works for me (it works above 120 but I set it to 200 to be on the safe side), but we can decide on a safer value depending on other's tests.2 points
-
Sounds interesting. I'll look into this as a future option, as it would make a lot of sense in a single-install, multi-site environment.2 points
-
I hope so too. But I've got a big GitHub issues list to work through, and a few more new things to polish off, so it may be awhile yet. But rather than waiting, I'd encourage folks to use the dev branch. Though I'm wondering if we might benefit from having another "beta" branch, which would be a variation of the dev branch intended more for official presentation and download links, etc.2 points
-
Hey Wanze, Looks like it is here: https://github.com/ryancramerdesign/ProcessWire/blob/a8024bb49785370aa2e3867bd683094663cfeabf/wire/core/PagefilesManager.php#L135 with $this->path() coming from: https://github.com/ryancramerdesign/ProcessWire/blob/a8024bb49785370aa2e3867bd683094663cfeabf/wire/core/PagefilesManager.php#L166 The createPath function is calling this: https://github.com/ryancramerdesign/ProcessWire/blob/a8024bb49785370aa2e3867bd683094663cfeabf/wire/core/Functions.php#L184 I guess it might need the mkdir recursive switch set to true in the wireMkdir function. Is that what you are looking for, or am I missing your point? I think maybe I am2 points
-
Thanks to Ryan, in the dev-branch we now have Pageimage::isVariation() hookable. I have added a hook to the init() method of PiM $this->addHook('Pageimage::isVariation', $this, 'isVariationWithPim'); and with this method all valid pimVariations of a Pageimage get collected / deleted together with the other variations of the original image: public function isVariationWithPim($event) { $variationName = basename($event->arguments[0]); if('pim_'!=substr($variationName,0,4) || false!==$event->return) { // if the result of hooked method isn't false, or if the file doesn't start with 'pim_' we leave now return $event->return; } // ok, imagefile starts with 'pim_', does it belong to the pageimage? $pageimage = $event->object; // get the pageimage $basename = basename($pageimage->name, '.' . $pageimage->ext); // basename of pageimage $re = '/^pim_.*?' . $basename . '.*?' . '\.(gif|jpg|png)' . '$/'; // regexp to identify if it's a valid pim_variation if(preg_match($re, $variationName)) { // we have a match, now return array with imageinfo // (the following rows are taken from original method Pageimage::isVariation(), only regexp is modified) $re2 = '/^pim_.*?' . $basename . '\.' . // pim_(prefix)_myfile. '(\d+)x(\d+)' . // 50x50 '([pd]\d+x\d+|[a-z]{1,2})?' . // nw or p30x40 or d30x40 '\.(gif|jpg|jpeg|png)' . // .ext '$/'; preg_match($re2, $variationName, $matches); $info = array( 'original' => $basename . '.' . $pageimage->ext, 'width' => $matches[1], 'height' => $matches[2], 'crop' => (isset($matches[3]) ? $matches[3] : '') ); $event->return = $info; return $event->return; } return false; } The next release of PiM (0.1.1) will have that.2 points
-
Hi folks, as announced yesterday, I just published my new Template Twig Replace module on github. The module lets you write Twig templates directly, making calls like $page->twig('my_template.twig') in an otherwise empty php template unnecessary. It also seamlessly integrates with my other module Template Data Providers that can be found here and here. Be sure to consult the README.md for further information. Please leave your comments, opinions, and suggestions here in this forum or at github and I'll try to answer as quick as possible. Honorable mentions go to porl and his Template Twig module for inspiring this little piece of code. Regards, Marco1 point
-
Last week I found a CSS framework called pure. Although there are plenty of good CSS framework out there, but sometimes those frameworks have just to much. Pure on the other hand is a small collection of css files. I like this approach, think I gonna use it in the next project. Base 1.2KB, Grids 0.9KB, Forms 1.4KB, Buttons 0.8KB, Tables 0.5KB, Menus 1.2KB Take a look: PURE1 point
-
I just discovered an awesome app: http://vanamco.com/ghostlab/ It lets you connect your devices (or simulated/emulated devices), then you test on one browser and the other views act synchronised. Debugging is easy too, you pretty much have a chrome dev tools like thing for all the devices on your desktop. Gosh this is front end heaven =)1 point
-
Wow! Isn't this a truely amazing community!!! I am so so so grateful to Adrian for having created this! I'm trying to create a site that will help categorize and show videos from my Vimeo account. The oembed module from Ryan makes it so easy to just copy the url and paste it into our text editor. This was one great great step forward. The thing that was missing / needed imho was a way of automatically fetching the thumbnails of these videos so that when we create a list of video episodes with a title and description, we could make these excerpts and our page of results way more interesting and media rich by displaying a thumbnail of our video as well!! I'm one slow learner. Go ahead and laugh... but the first thing I thought of to do all this was create an image field and then looked for a screen capture program that could take a picture of the oembeded video showing on my page at full size, and then manually feeding that screen grab into a custom image field for the page to subsequently display it resized into a thumbnail. So i thought after doing this the manual way, surely the video hosters might give you a way of extracting an image from the video and sure enough, looking at the Vimeo API, they did. And so I wrote to Adrian asking him if he could help me / point me into the right direction as to how to go about doing this. I initially thought that we needed to modify Ryans oembed module. But Adrian explained to me that way to go about it conceptually was to create a hook before you save the page, get the image from Vimeo or whoever, and use the PW API to save this to an image field. Ahhh... an Eureka moment for me! Now hooks in PW make more sense to me and of course having the obvious need for this hook, we now know that we need our PW API for saving an image so the API's relevance seems much greater now too!! Somethings abstract instantly become a developers best friends!! BTW, I used hooks in WordPress quite a bit as basically there were so many things you wanted WP to do differently, and so hooks are typically used there to swap out and change the behaviour of a particular function. But I never really looked at hooks in PW as it seems to do everything right in the first place and as a result never really had any reason to even look into them Anyways... can't wait to try this module and see how it works! Thank you Adrian !!!!!!!1 point
-
Wanze, Adrian is right with the _createPath() function he linked to. It maybe that you could solve it entirely simply by making it recursive, as he suggested. Actually, it might be good to just have the wireMkdir() function support creating a path rather than just a single directory... lets update that one in the core instead. The wireRmdir() already supports a $recursive argument to it, so wireMkdir() should too.1 point
-
I realize I sound like a broken record in this thread, but thanks again for your great work with this language pack. This is the most complete and up-to-date language pack for PW.1 point
-
Just to confirm, sessions are working (i.e. you are able to stay logged in consistently), but you just don't see anything in the Setup > Sessions page? Is it completely empty, or do you just see yourself there? In testing here, I can't seem to duplicate the issue. Double check the top drop-down box that lets you specify how many minutes you want to see sessions for. Make sure it is set to at least 5 minutes. If doesn't do it, try increasing it to 43200 minutes and see if that makes any difference? Another thing to double check is caching. If you are using ProCache, you will not see sessions appear here except when PW has to render the page. That's because ProCache bypasses sessions and the overhead associated with them. So not seeing sessions here would be expected and desirable, but only if using ProCache. Last thing to look at is your Modules > Session > Session Handler DB module settings. Try enabling (or disabling) "track IP addresses" and/or "track user agent" in the settings, to see if it makes any difference.1 point
-
@rooofl, sorry, I didn't see your questions before. Yes, that's right, you can't have pages previously selected on a page field. What you want would require a module that hooks on page save and selects the page being saved on all the selected pages from the field on that page. Sounds confusing but it's quite simple. $selectedPages = wire($page)->field; foreach($selectedPages as $p){ $thisPage = wire($page); $p->field->add($thisPage); $p->save(); } Written on the browser and I don't have time to make it more complete. Just to give an idea.1 point
-
Kind of pointing out the obvious, but the code Pete posted creates config ARRAY, while interrobangs approach creates OBJECT. It really doesn't matter which one you use here (especially considering that PHP array syntax isn't exactly pretty), just wanted to clarify the terminology a bit for any "OOP beginners" stumbling into this thread..1 point
-
I did a quick test and this seems to work too: $config->var = new stdClass(); $config->var->item = 'val1'; echo $config->var->item;1 point
-
I like the idea of this. Though my need is less the part of reusing existing fields, but creating a fieldgroup bundled with its fields. For sure it would a nice if I could even reuse existing fields like "title" and access them like somehow like this "$page->myfieldgroup->title", but I never missed this feature. I try to explain my usecase: I have some templates with a fieldgroup "metainfo" with the fields "browsertitle" and "meta_description". Currently I have to assign all these fields one by one to my templates. And if I later need some additional meta infos for facebook like "og_image" and "og_title" I have to edit all my templates to add these fields. If we would have some kind of defined fieldset, I could just assign my new fields to this fieldset and all my templates would have the new fields.1 point
-
Ok, continuing the monologue: I helped myself, simply generating ANY new userAuthSalt. After that I used Ryans explanation to reset admin and user passwords: http://processwire.com/talk/topic/1736-forgot-backend-password-how-do-you-reset/?p=16163 Logins and everything else works fine now.1 point
-
That's fair enough regarding the head.inc etc... I used the convention of a file named _init.php based on the way you use prependTemplateFile in your example site profiles, but spex just automatically calls is before the page render event. addStyles/etc... are in fact using $config->styles internally. They're just there as a bit of syntactical sugar and to handle the compiling of .less files.1 point
-
Czech Localization Pack. Current version: 0.9.7 (93 files) + README.txt Changelog: Added some missing strings (LanguageSupport modules) Updated some strings Czech Localization Pack for external modules. Current version: 0.2 (15 files) + README.txt Changelog: Added: FormBuilder /site/modules/FormBuilder/email-administrator.php /site/modules/FormBuilder/email-autoresponder.php /site/modules/FormBuilder/FormBuilderConfig.php /site/modules/FormBuilder/FormBuilderEmail.php /site/modules/FormBuilder/FormBuilder.module /site/modules/FormBuilder/form-builder.php /site/modules/FormBuilder/FormBuilderProcessor.php /site/modules/FormBuilder/InputfieldFormBuilderFile.module /site/modules/FormBuilder/ProcessFormBuilderEmbed.php /site/modules/FormBuilder/ProcessFormBuilder.module Updated: InputfieldCKEditor pw_czech_097.zip pw_czech_modules_02.zip1 point
-
Here is another thread where we talked about frameworks. If size and flexibility matters, PocketGrid could be a good choice? It's only a grid, nothing more. Very minimal and seems to be very flexible. Looks like you can do anything with it (like doing with PW). But haven't tested it.1 point
-
I think Ryan means this: $pages = wire('pages')->find("template=property"); foreach ($pages as $page) { $page->images->deleteAll(); $page->save(); $page->images->add("http://images.com/image1.jpg"); $page->save(); }1 point
-
I do agree, if you have Apache and the technical know how to pull this off, then using Apache is the best method, because it will compress your css, js and other files (though you can compress js/css using php). The only problem with this approach is we are making the assumption that Apache is the only web server in existence and that users have the ability to enable and configure the Apache modules that are required to pull this off. Also, in many cases, these types of configurations should go into the vhost.conf for performance reasons. Vhost.conf will be read once when Apache restarts vs. .htaccess which will be read on each and every page request. The second part of the conversation is more interesting to me though. Will saving compressed data in the form of cache files be faster than saving uncompressed data? This is where I can see some potential value for using compression with PW. $compressed_cache = gzencode($data); // if you need to serialize use gzencode(serialize($data)) // for zlib compression use gzcompress($data) The when you are retrieving the cache file you can uncompress it... $value = gzdecode(file_get_contents()); // if you need to unserialize use unserialize(gzencode(file_get_contents())) // for zlib compression use gzuncompress(file_get_contents()) Or send it compressed if the browser supports this... if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) { $value = file_get_contents(); } else { $value = gzdecode(file_get_contents()); }1 point
-
After a lot of research I've found the solution, which is to make the Silex session handler wrap the existing session handler. So far, so good!1 point
-
Hi ryan I also got the 404 issue and I believe it is to do with how various browsers (maybe?) handle this line: header('Content-Type', 'application/json; charset=UTF-8'); Changing that to the following, my issues were resolved on Firefox: header('Content-Type: application/json'); Hopefully that helps others - I guess there may be something "non-standard" or maybe not globally recognised in the line that's in the module - it's all a bit beyond me, but this change resolves it1 point
-
While this technic is nice to know it is much easier to enable compression via .htaccess, also because of the reason Ryan mentions. I don't see any reason why to do this via PHP. See the H5BP htaccess for nice technic https://github.com/h5bp/html5-boilerplate/blob/master/.htaccess#L379 and other goodies. Also only while the html served might be 4kb instead of 24kb, this doesn't make the page load that much faster, but using this for all resources along with caching headers you get a ~30% decrease of file sizes. Using PW template cache can have the most impact on page loading, depending on how render intensive the page is, you get a loading time around factor 2-5 times faster just because it doesn't need to render it.1 point
-
thanks martin/SiNNuT for posting on pure; i was thinking of trying to build something with this soon: http://www.getuikit.com/1 point
-
http://processwire.com/talk/topic/3740-yahoo-css-library-httppurecssio/ All joking aside, this is a pretty neat resource and the soon to be released version has a more robust grid implementation. They do say so on the site, but keep in mind aforementioned file sizes are gzipped. Uncompressed it's more like 19 or 20 KB (still small though). Another one i'm trying out atm is http://cardinalcss.com/1 point
-
It's been awhile since I've worked with page compression, but here's what I remember. This checks to see if content is being gzipped by looking at currently loaded handlers and checking for zend compression (php isn't smart enough). If their is already a gzipped buffer it fires ob_start, if not php will start a gzipped buffer if the client supports compression, if not the output is not compressed (gz_handler is smart like that). if ((!ini_get('zlib.output_compression')) && (!in_array('ob_gzhandler', ob_list_handlers()))) { ob_start('ob_gzhandler'); } else { ob_start(); } As far as dealing with cached gzipped files, I wonder if you'll gain some performance by saving compressed data. There are php functions to dealing with compression, that will compress and decompress gzipped data. You'd handle this in the same way you would serialize data. gzinflate() - Inflate a deflated string gzdeflate() - Deflate a string gzcompress() - Compress a string gzuncompress() - Uncompress a compressed string gzencode() - Create a gzip compressed string A quick and dirty process flow would be something like this (keep in mind I haven't used the pro cache module nor do I understand yet how the default caching works)... save compressed data to file on the next page request start gzip if it's supported by the client else start the regular buffer route the request and get the cache file decompress and unserialize the cache file and dump into the current buffer. Data is uncompressed at this point and only compressed back if gzip is supported by client. (I wonder if it's possible to dump a compressed cache file into the current buffer and only decompress if the client doesn't support compression.) flush the buffer and display the page As far as advantages, there are probably less for PW. I see using gzip with php as an advantage in distributable applications targeting users w/ little to know programming or server admin knowledge. For those folks on shared hosting who want to install and go without hassle, this is a good option for them. It provides a big boost in performance w/o the additional configuration of apache or apache modules. Perhaps another advantage is being less dependent on the server environment and knowledge of the end user and controlling more aspects of how the app works inside of the app. All of that being said, in most cases Apache will be a better choice followed by zlib compression. Apache will also compress the js and css. The disadvantage is not all of your community will be running mod_gzip and may have no option to enable it (shared hosts). A config checkbox would allow advanced users to turn it on/off php compression if they wanted to use other methods like apache or zlib. Even if you don't use compression with the output buffer, there could be enough of a performance boost to consider using it to compress your template files before saving them. Here's how to retrieve data Unserialize(gzuncompress(file_get_contents())).1 point
-
Just stumbled on this http://scrollback.io/. Could be a nice solution to bring the IRC channel to the forum.1 point
-
Next to this, wrapping block elements in links, can reduce markup, create a bigger click area & you get a styleable container for free This is great!1 point
-
Hi Emmanuel, its's very easy to convert data to PW if you start thinking in tree instead of table structure. Let's say json/mongo vs mySQL/excel. One important thing to have in mind is that besides the parent child structure you have also the possibility to connect the branches of the tree with page fields, which makes it very flexible. I think the best way to structure data is to convert 1 to 1 relations as parent/child connection, and 1 to many relations as page field connections. When you query the database with PW, the "pages" are stored in a pageArray object. Obviously, if you have lots of data, this will empty your memory very quickly. That's why you should always limit your queries ("limit=50") and paginate the results when needed.1 point
-
Hi Gabi, There's no difference between calling ->field or ->get('field'); First is routed through PHPs magic getter ( __get() ) and will call the get() method behind the scenes... If you want to have global variables available all the time, why not just store them in a variable, e.g. $global? No need to assign them to the actual $page variable: // Store page in $global or $sys $global = wire('pages')->get(1222); // Later in any template... just get the values from your variable echo "<div id='contact'>{$global->contact_name}</div>";1 point
-
In the end I did it that way after reading Soma's post: app.js var app = angular.module('app', []); app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/clientes', {templateUrl: '/partials/clientes', controller: 'prueba'}). when('/mascotas', {templateUrl: '/partials/mascotas', controller: 'prueba'}); }]); app.controller('prueba', function ($scope) { $scope.model = { cliente: "John "}; }); /partials/ (partials.php) <?php switch ($input->urlSegment1) { case "clientes": include("./partials/clientes.php"); break; case "mascotas": include("./partials/mascotas.php"); break; default: break; } ?> and then a php file for each partial, so you can make use of ajax, and the power of processwire api. clientes.php <div>tu partial template {{model.cliente}}... </div> mascotas.php <?php echo $page->name; ?> <p>mascotas</p>1 point
-
You would need a script for sure for importing data. But you have to divide the task in three: 1. Build the "site theme" in processwire. This is not more than identifying all the different pages on the website, divide their html by templates and replace the dynamic parts. 2. Mirror the website structure in the PW tree. 3. import the previous content to the new site. Your site seems to follow a very simple structure (not too different from the default PW website, so you can take some ideas from there), I would say 5 templates maximum: Home, basic-page, blog, contact, site-map. Header and footer would be the same in all templates, being that home would have a subheader (very easy since that one just follows the header in the markup). basic-template would need only two fields: body and headline and and title (this is for mirroring the website as is, although with processwire you could actually make the content richer by creating more specific templates. But let's stick to mirroring the website for demonstration purpose). The structure could be something like: Home (render "Poland" page) -- Poland (headline: Poland Explorer Travel and Tourist Guide) ---- About Poland Explorer ---- How to use Poland Explorer ---- ... -- Provinces (headline: Provinces of Poland) ---- Poland Explorer Travel and Tourist Guide ---- About Poland Explorer ---- ... -- Geography (headline: Geography of Poland) ---- Map of Poland ---- Mountains of Poland ---- ... -- History (headline: History of Poland) ---- Heads of State of Poland ---- Katyn Forest Massacre ---- ... -- Other Activities ---- Aviation ---- ... -- Blog ---- Article 1 ---- Article 2 ---- ... -- Contact&Search -- Sitemap (hidden from navigation) The basic template would be something like this: <? php include('head.inc'); php include('sidebar.inc'); echo $page->headline; echo $page->body; php include('footer.inc'); Yes, that simple! sidebar.inc would be something like: <div class="column fourcol"> <?php include('search.inc'); <h4><?php echo $page->headline; ?></h4> </div> <div class="widget widget_nav_menu"> <ul id="menu-provinces-of-poland" class="menu"> <?php $children = $page->children->count ? $page->children : $page->siblings; foreach($children as $c) { echo "<li><a href='{$c->url}'>$c->highlight</></li>" } ?> </ul> </div> ...and so on. There are plenty of examples in the default site that would fit very well in practically all problems you would find. The importing part is well covered in Ryan's post that was linked above.1 point
-
If I understand you correctly, this sounds like a job for Hanna Code: http://mods.pw/4b1 point
-
You need to load the route module additionally to angular.js http://code.angularjs.org/1.2.0rc1/ <script src="http://code.angularjs.org/1.2.0rc1/angular.js"></script> <script src="http://code.angularjs.org/1.2.0rc1/angular-route.js"></script> <script src="js/app.js"></script> app.js angular.module('phonecat', ['ngRoute']). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}). when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}). otherwise({redirectTo: '/phones'}); }]); where partials/phone-list.html could also be a PW page url with a partials template with url segments enabled create a page: /partials/ then the route configured like: /partials/phone-list and in the template file if($input->urlSegment1 == "phone-list"){ echo "<div>your partial template ... </div>"; }1 point
-
Hi everyone, I made a walkthrough of a web app I built using ProcessWire for the Tenova Group mining company. They needed an intranet application to keep track of their daily plant operations. I designed and developed a ProcessWire solution that would allow registered employees at Tenova HYL to record events regularly in an event log. Storing all of the events in this manner would allow registered users to find the events they're looking for using keyword search, date filters as well as filters based on other criteria. Each event also allows the user to upload supporting files for download, such as Word documents and PDFs, as well as upload relevant images to be displayed in a modal window. A high-performing, powerful solution using the ProcessWire CMS. Read about the project here in my portfolio. See the video here: Tina Holly tinaciousdesign.com1 point
-
Update. Font size is now 14px for all base fonts, heading/nav are mostly 16px. Sidebar action shrink down. I think we now have enough space for most page trees. Removed the boxes around the fields as suggested by apeisa. Thin lines to seperate them, especially the multi-column fields. Not sure about this one, because it' really defines the "look" of the PW admin. Updated setup view added. Now looking forward to do more on those fields. Repeaters and image uploads, fieldset. Note: You can use this design under a Creative Commons BY-SA 3.0 licence. Of course, the ProcessWire logo is owned by Ryan Cramer and the Icons are taken from Entypo. Contact me, if you want the layered files or sliced graphics.1 point
-
@ryanscherler i've been doing that sort of thing by just using 2 hanna codes, one for the opening markup and one for the closing markup; like this: [[col2]] This is a block of content... [[_col2]] eventually if the shortcodes module supports more than 1 shortcode per page, then this would be pretty easy to do with shortcode; the biggest thing i'm lacking now in terms of hanna/shortcode is with respect to tabs and accordions, and being able to sometimes put a set of tabs inside a body content; like this: [[tab title=Tab 1]] Tab content 1 [[tab title=Tab 2]] tab content 2 [[/tabs]]1 point
-
Hey Ryan, How would you recommend using Hanna code to wrap a larger amount of markup? For example, if a client wants to create a two column layout within a body section. E.g. In TinyMCE: [[col2 content= This is a block of content... ]] This seems to work with the following simple PHP as a hanna code tag: <?php echo "<div class=\"column\">\n".trim($content)."\n</div>\n"; ?> When its output, I get invalid formatting much like this: (with closing and opening tags still being output due to breaks in hanna code tag within TinyMCE. <div class="column"></p><p>This is content</p><p></div> Would there be a way to create a hanna code tag wrapper type? E.g. [[col2]] This is a block of content... [[/col2]]1 point
-
From the README file (given this, I think your example would work): Using Hanna Code from the API If you want to populate Hanna Code from the API, you can do so using the render() method, like this: $hanna = $modules->get('TextformatterHannaCode'); $page->body = $hanna->render($page->body);1 point
-
Now we have this, I can imagine we have a "snippet" bucket somewhere were we can share some high quality "snippets".1 point
-
Sorry about that, I went back and forth on the name a couple times and ultimately entered the wrong class name in the modules directory. It should have been TextformatterHannaCode, not ProcessHannaCode. I have corrected that. I was throwing an exception when I shouldn't have. I'm pushing a correction for this. Technically they are part of the same program "Hanna Code", even if that program has two modules. But I know what you mean. I'm adding "(Process)" to the Process one, just so that the two next to each other can be differentiated. Also, one more section I just added to the README: Using Hanna Code from the API If you want to populate Hanna Code from the API, you can do so using the render() method, like this: $hanna = $modules->get('TextformatterHannaCode'); $page->body = $hanna->render($page->body);1 point
-
Go ahead and make your module implement ConfigurableModule, even if you don't want any interactive configuration: class MyModule extends WireData implements Module, ConfigurableModule { Add a getModuleConfigInputfields function to your class that just does this: public function getModuleConfigInputfields(array $data) { return new InputfieldWrapper(); } For data that you want to store, call upon the $modules API var like this: $data = array('foo' => 'hello', 'bar' => 'goodbye'); wire('modules')->saveModuleConfigData($this, $data); For data that you want to retrieve: $data = wire('modules')->getModuleConfigData($this); Your config data will be populated to your module automatically after __construct() but before init(). As a result, you might want to set default values in your __construct(): public function __construct() { $this->set('foo', 'hi'); $this->set('bar', 'bye'); } public function init() { // $this->foo is now 'hello' (not 'hi') // $this->bar is now 'goodbye' (not 'bye') } Using this method, your module can always access it's config data directly via $this->foo and $this->bar. Meaning, you probably won't ever need to use the getModuleConfigData() function, but it's good to know its there. However, you will need to use the saveModuleConfigData() function since you are saving configuration data non-interactively.1 point