Leaderboard
Popular Content
Showing content with the highest reputation on 03/15/2015 in all areas
-
5 points
-
Cycle2 works wonders for me. ResponsiveSlides is nice and clean, but lacks support for some features I tend to need (such as custom markup).4 points
-
It's actually quite straightforward. In your field settings, under Input, add a reference to a JS Styles Set: mystyles:/site/modules/InputfieldCKEditor/mystyles.js If you're using the blank profile, that file won't exist. If so, you'll need to copy the one from wire/modules/Inputfield/InputfieldCKEditor. All that's left is to add the style you want for your paragraphs. Your file should look like this: CKEDITOR.stylesSet.add( 'mystyles', [ { name: 'Inline Code', element: 'code' }, { name: 'Inline Quotation', element: 'q' }, { name: 'Left Aligned Photo', element: 'img', attributes: { 'class': 'align_left' } }, { name: 'Right Aligned Photo', element: 'img', attributes: { 'class': 'align_right' } }, { name: 'Centered Photo', element: 'img', attributes: { 'class': 'align_center' } }, { name: 'Small', element: 'small' }, { name: 'Deleted Text', element: 'del' }, { name: 'Inserted Text', element: 'ins' }, { name: 'Cited Work', element: 'cite' } // plus your style { name: 'Summary', element: 'p', attributes: {'class': 'summary'} } ] ); Then, you can select your whole paragraph and choose the Summary style for it. Edit: Might also be a nice idea to add a CSS file to apply the style in the editor too. Edit: Hold up, I see you're wanting this to happen automatically for the name of the field... Didn't pick that up, sorry. That said, this is cool for a targeting specific paragraphs.4 points
-
I used Slick on several projects and it worked really well. There's also http://www.idangero.us/swiper/ which is similar to slick but with more options regarding the transitions and layout.3 points
-
If the reset password functionality is part of the website you build, i do think it is your responsibility to explain to the client the pro's and cons of the different methods and let them choose. The method you describe is weak but convenient, the method with personal security questions is (at least to me) annoying but much more secure if done right. A pretty good write-up here: https://fishnetsecurity.com/6labs/resource-library/white-paper/best-practices-secure-forgot-password-feature Which also made it to the OWASP site: https://www.owasp.org/index.php/Forgot_Password_Cheat_Sheet3 points
-
I like this due it's minimalistic footprint. http://responsiveslides.com/2 points
-
Template Cache and $page->render($options) If you ever use the $page->render() to render out partials (of another page using its template file) and use template cache for the pages you're going to render and the page where you render it, it will create a cachefile. So if you go to that previously rendered and cached page, it will render that partial. If the page is accessed before a cache is created, it will cache this one and render that in as the partial, so kinda turned around. Funny effect. And many mmms and oaaahhhs To get a better understanding what's happening read on. Simple example code from a list page to render partials of articles (likely) // from the list pages template $markup = ''; foreach($products as $key => $child) { $markup .= "<dl>"; $markup .= $child->render(array('isOverview' => true, 'class' => $class)); $markup .= "</dl>"; } echo $markup; And in the template of the article // in article template file if(isset($options['isOverview']) && $options['isOverview'] == true) { // render small partial $class = $options['class']; $markup = "<dd class='$class'> <h4>$page->title</h4> <p>$page->summary</p> <a href='$page->url'>details</a> </dd>"; } else { // render complete article $markup = "<div class='product-details'> <h1>$page->title</h1> $page->body </div>"; } // output echo $markup; So now the render call $markup .= $child->render( array('isOverview' => true, 'class' => $class) ); in the list template will cache the page it renders (the small view of it). Thus if you access the page directly it will serve the cached small view of it. Ups. Solutions This is without specifying a different template file in the first argument in the render(). The effect doesn't happen when you, let's say create a new template file (ie article-small.php) and use that to render the page. Since this new template file is not connected to the template in PW it also has no cache for that render. To show what I mean is the following with the first argument the file you want the view to render. $markup .= $child->render("product-small.php", array("isOverview" => true, "class" => $class)); Still following me? Ok there's also another method to not allow a cache file to be created. There's a default options set in the render() in PW. Bingo! allowCache is what we can also use. $markup .= $child->render("product-small.php", array( "allowCache" => false, "isOverview" => true, "class" => $class )); And everything's back to normal. Just wanted to write down a little thing, as I stumbled over this recently, to scatter some keywords about this here . I think this isn't really documented somewhere but I thought it was maybe mentioned by Ryan in a thread about when he added this feature: http://processwire.com/talk/topic/3145-multiple-views-for-templates/page-2?hl=%2Brender+%2Bcaller#entry32876. Edit: Zaaakkkk and it's in Google 9 minutes !1 point
-
Hello there Yesterday we at update AG relaunched the new 1815.ch news portal of Mengis Medien AG. It's a big new portal of a local newspapers here in Wallis Switzerland. That's where the Matterhorn is also It was a thrill to work on this project using ProcessWire. We're still working out some details and adding more stuff in future. There's a lot going on and it has quite lot of traffic. 60k+ pages at the moment. Currently it serves 18k+ articles plus a lot of other data that are just pages. But will grow a lot. The portal has currently around 7k+ user registered. Lots of imports and exports are going on in the background. That mostly are XML feeds or data being uploaded to server. Some news are imported and automated. While they have different teams creating articles apart from the imports of their newspaper also via XML. http://www.1815.ch1 point
-
Get it from GitHub Setup Just put the module in you modules directory and install it via admin. Intro This module might come in handy if you like to keep your templates clean and free of unreadable and unmaintainable string concatenations and even free of any logic. It also comes with some handy features besides just embedding JS, CSS and image assets, see below. Yikes! <link href="<?php echo $config->urls->templates . 'styles/foo.css'; ?>"> <link href="<?php echo $config->urls->templates . 'styles/bar.css'; ?>"> <script src="<?php echo $config->urls->templates . 'scripts/foo.js'; ?>"></script> <script src="<?php echo $config->urls->templates . 'scripts/bar.js'; ?>"></script> <img src="<?php echo $config->urls->templates . 'images/sky-scraper.jpg'; ?>" alt="Some huge building"> <img src="<?php echo $config->urls->templates . 'images/owzim.jpg'; ?>" alt="Handsome!"> Way cleaner <?php echo $asset->css('foo'); ?> <?php echo $asset->js('foo'); ?> <?php echo $asset->img('sky-scraper.jpg', 'Some huge building'); ?> or with short syntax <?= $asset->css('bar') ?> <?= $asset->js('bar') ?> <?= $asset->img('owzim.jpg', 'Handsome!') ?> And prettier if you're using Twig {{ asset.css('foo') }} {{ asset.css('bar') }} {{ asset.js('foo') }} {{ asset.js('bar') }} {{ asset.img('sky-scraper.jpg', 'Some huge building') }} {{ asset.img('owzim.jpg', 'Handsome!') }} Usage JS example Let's use the js method an its configuration as an example, and assume we have the following files located in /site/templates/scripts - index.js - index.min.js - main.js $config->blick = array( 'jsPath' => $config->paths->templates . 'scripts', 'jsUrl' => $config->urls->templates . 'scripts', 'jsMarkup' => '<script src="{url}"></script>', 'jsDefault' => 'markup', 'jsVersioning' => true, 'jsVersioningFormat' => '?v={version}', 'jsMin' => true, 'jsMinFormat' => "{file}.min.{ext}", ); $asset = $modules->get('Blick'); $asset->js('index')->url; // returns /site/templates/scripts/index.min.js?v=1426170460935 // 'min' and version parameter added, which was fetched from the file modified date $asset->js('main')->url; // returns /site/templates/scripts/main.js?v=1426170460935 // without 'min', because there is no main.min.js $asset->js('main'); // returns <script src="/site/templates/scripts/main.js"></script> // because 'jsDefault' is set to 'markup' // you can also access it explicitly via $asset->js('main')->markup $asset->js('http://code.jquery.com/jquery-2.1.3.js'); // returns <script src="http://code.jquery.com/jquery-2.1.3.js"></script> // nothing is modified here, because it's a remote url You can use the file name with or without extension. Adding a version parameter only takes place, if jsVersioning is set to true, it's a local file and it exists. Modifying the file name to include min only takes place, if jsMin is set to true, it's a local file and it exists. The same applies for the $asset->css('file') method: $config->blick = array( 'cssPath' => $config->paths->templates . 'styles', 'cssUrl' => $config->urls->templates . 'styles', // and so on ... ); IMG example the img method lets you include images, crop and resize them, without them having to be a page image. $config->blick = array( 'imgPath' => $config->paths->templates . 'images', 'imgUrl' => $config->urls->templates . 'images', 'imgMarkup' => '<img {attrs} src="{url}" alt="{0}">', 'imgDefault' => 'markup', 'imgVariationSubDir' => 'variations', ); $asset = $modules->get('Blick'); $asset->img('sky-scraper.jpg')->url; // returns /site/templates/images/sky-scraper.jpg $asset->img('sky-scraper.jpg', 'Some huge building'); // returns <img src="/site/templates/images/sky-scraper.jpg" alt="Some huge building"> // any arguments following the filename are passed as an array // in this case the alt value is the 0th argument, so {0} get's replaced // you can set as many arguments as you want in 'imgMarkup' $asset->img('sky-scraper.jpg')->size(100, 100)->url; // returns /site/templates/images/variations/sky-scraper.100x100.jpg // the resized image is put into a subdir 'variations' as configured in 'imgVariationSubDir' // if 'imgVariationSubDir' is left empty, the variation will be put in the same directory $asset->img('sky-scraper.jpg', 'Some huge building')->attr('title', 'Some huge building'); // returns <img title="Some huge building" src="/site/templates/images/sky-scraper.jpg" alt="Some huge building"> // the resized image is put into a subdir 'variations' as configured in 'imgVariationSubDir' // if 'imgVariationSubDir' is left empty, the variation will be put in the same directory You can also setup predefined variation settings in imgVariations $config->blick = array( 'imgVariations' => array( 'header' => array( 'width' => 960, 'height' => 360, 'options' => array( 'suffix' => 'header', ), ), 'person' => array( // and so on ... ), ), ); And call it like so: $asset->img('sky-scraper.jpg')->variant('header')->url; // returns /site/templates/images/variations/sky-scraper.960x360-header.jpg $asset->img('sky-scraper.jpg')->variant('header', 50)->url; // returns /site/templates/images/variations/sky-scraper.480x180-header.jpg Attributes example Since version 0.4.0 you don't need to create arbitrary variable placeholders, if you want to use attributes only. Now you can use the {attrs} placeholder and set the attributes via $asset->attr('name', 'value'). The name argument can also be multiple names, split by a pipe |. $config->blick = array( // ... 'imgMarkup' => '<img {attrs} src="{url}">', // ... ); $asset->img('sky-scraper.jpg')->attr('alt|title', 'Some huge building'); // returns <img alt="Some huge building" title="Some huge building" src="/site/templates/images/sky-scraper.jpg" > Using files that are not in the configured directory If you want to include files, that are neither in the configured directory nor in one of its sub directores, just use an absolute path (actually, relative to your /site directory. $asset->js($config->urls->SomeModule . 'scripts/file-in-root'); Autoload the module If you don't want to include the module manually via $assets = $modules->get('Blick'); you can set it to be autoloaded under a custom name: $config->blick['autoloadAs'] = 'fiddle'; Now it becomes automatically available in your templates under the name fiddle $fiddle->css('foo'); $fiddle->js('foo'); $fiddle->img('baz.png', 'qux'); Please note, that, if you're using the TemplateTwigReplace.module you will have to add your chosen autoload name to the Auto-import fuel list on the module's config page. See config-example.php for all configurable settings. Change Log 0.5.0 add optional scale argument to variant-method: $asset->img('foo.jpg')->variant('header', 50) 0.4.0 add possibility to get/set and render attributes (see section Attributes example) 0.3.0 add $asset->variant('name') alias for $asset->getVariation('name') 0.2.0 fixes and internal refactorings 0.1.0 initial version1 point
-
Hi there, In the past, I've used RoyalSlider for slide shows but generally find it a bit "convoluted". I also use an image caching service that serves up the best images for the page/device/bandwidth and because a piece of JS fetches the images (based on html5 attributes), this can cause a few issues with slideshows. I just wondered whether there is any particular slideshow used by PW devs that is considered to be really good? I'd appreciate any recommendations! Cheers.1 point
-
I've used Owl carousel with loading images via JSON (+ fancybox for the lightbox part): http://owlgraphic.com/owlcarousel/demos/customJson.html ResponsiveSlides looks pretty neat, will try it in the next project.1 point
-
I used bx-slider for a while until I found out that with many slides it really starts to drain resources. In windows taskmanager under the Tab performance I could see the bar go way up. So in chosing an image slider check how much resources it is going to drain.1 point
-
Can't remember which service it was, but just recently I had to fill in a series of *required* security questions when signing up. There were a couple of them, ranging from "what's your mothers maiden name" to "what's the name of the city you were born in". In short, all of those were questions that anyone can dig up in an hour or so, quite likely without even relying on social engineering. I sincerely hope that they don't use that crap to "validate" anyone. In either case, they didn't provide any details about how that data is used (as an addition to email validation, or on it's own), so just to be sure I filled in some incomprehensible random stuff. I definitely won't be able to answer those questions -- but neither will anyone else. Password recovery based on email is, in my opinion, relatively safe on it's own. Safe enough for most services out there anyway. Of course it's always a question of "how much security does this service require"; combining it with security questions can enhance it's reliability, switching emails to text messages is considered even more secure (and harder to set up), and so on1 point
-
1 point
-
I had the same issue with ProcessJumplinks at one point. Can't remember what caused it, though... Drove me mad.1 point
-
This solves it for now #content .WireTabs a { max-height: 37px; } #content .WireTabs { margin-top: -38px; top: 0; margin-bottom: 0; }1 point
-
@Kongondo, I do think it has something to do with not getting the height properly for .WireTabs.nav or white-space injection on the javascript side. (What Javascript does when manipulation the dom) I have found a solution (not good) .with CSS for now. Doesn't work for pill tabs // CSS .WireTabs.nav { height: 2.4em; } #content .WireTabs a { height: 2.4em; } And thanks for your answer @LostKobrakai1 point
-
1 point
-
1 point
-
I just woke up this morning and that thought crossed my mind while not create a hook to page to render the admin if the page url is member-dashboard but i put that logic in the member-login instead and it works, i guess my issue is am still stuck with the concept of other Framework's way of doing things. Thanks for the response.1 point
-
That brings it's issues, too, see here: https://github.com/ryancramerdesign/ProcessWire/issues/9691 point
-
I could swear I tried that. Working now thanks1 point
-
So, https://github.com/ryancramerdesign/ProcessWire/archive/dev.zip isn't working?1 point
-
1 point
-
1 point
-
In your foreach gallery loop you are creating many lightboxes with the same ID: <a href="#gallery" class="lightbox" id="image_gallery"> ID's should be unique, only one per page is allowed with the same name. Try something like // before the loop: <?php $counter = 1; ?> // in the loop: <?php $currentID = "image_gallery_" . $counter; ?> <a href="#<?php echo $currentID; ?>"> <a href="#gallery" class="lightbox" id="<?php echo $currentID; ?>"> <?php $counter++; ?> Then you will have IDs like "image_gallery_1", "image_gallery_2", etc.1 point
-
This is the intended behavior of the AutoDetect Language module. It will only run on the first page load, to set the $user->language setting, which is created from a session variable. There is no need to detect language on each page load (and you really shouldn't, to be honest), as it's set once by PW and it will reuse it on each page load unless it's overwritten by setting $user->language manually. If you need to check if AutoDetect Language has run (and reuse its state somewhere else), there are two session variables I created (that you can read about in the documentation). If you want to force it to run again, you can set $session->languageAlreadyDetected to false, but I wouldn't say it's generally advisable.1 point
-
I opened an issue in the Mobile Detect github space regarding how this module installs. Reference https://github.com/justonestep/processwire-mobiledetect/issues/11 point
-
I know there are benefits and drawbacks to different approaches, so I'll try to explain why PW uses the approach it does, and respond to some of the points above. The approach described as an alternative here is similar to what I've used on other projects, including PW1. I was really looking to come up with something different for PW2. The goal was to make it as absolutely simple as possible for people to add hooks and for people to make methods hookable. I wanted it to be in the background and everywhere, so that you really didn't even have to think about it. It's not designed for ease of consumption by xdebug, I'll give you that. But it is designed for ease of consumption by you and me, which I consider more important. Admittedly I don't use xdebug very much anymore, so designing things for xdebug has not been a priority. When you start a new CMS project, you are in a crowded space, so you have to come up with things that are different. So one of the ways ProcessWire differentiates itself is by making hooks easier to hook into and create than they are in other platforms, and I'd like to keep to that. When it comes to PW's code base, I consider it important to not add complexity purely for sake of static analysis. From my perspective, static analysis is a good thing, and I'm more than happy to let it dictate the direction of comments and what supports the code. But when it starts to dictate the direction of the actual code towards unnecessary complexity/verbosity, less efficiency or reduce the simplicity of the API, then I consider it no longer helpful. If ProcessWire were just a PHP framework and coders in IDEs were the primary audience, then I would feel differently. But for ProcessWire's audience and growth, when I'm confronted either making my IDE happy (and related tools like xdebug), or making the API (or related things like hook system) as simple and as good as they can be, I'm always going to choose what's best for PW's API and systems. My preference is making both happy. But when you are doing something different, existing tools won't always be familiar with it. For something like the hook system, there was definitely a conscious decision to go with what's best for PW and PW users, over what's best for static analysis or xdebug. All the add hook methods are actually handled by just one method: addHook(). The point of the other methods (mentioned below) is to make things simpler for you, and make your code more readable. I prefer verbose method names to boolean and array arguments because they are self describing. think this is a benefit, not a drawback. Use addHook() if you want to add a method to a class that isn't already there. Use addHookProperty() if you want to add a property (rather than a method) to a class. Use addHookBefore() if you want to hook before an existing method (and have the option of modifying arguments sent to it). Use addHookAfter() if you want to hook after an existing method (and have the option of modifying the return value). Regarding the distinction of hooking a class name or an object, this is also meant to be a help to you: The purpose of being able to call a hook on a class name is so that you can hook ALL instances of that class (current and future). The purpose of being able to call a hook on an object is to hook only that single instance of the object. As for ease of finding hooks, this is also something I've tried to make as simple as possible by using a convention that you won't see elsewhere in ProcessWire: 3 underscores prepended to a method. So while you can use CaptainHook, I'm not sure you need to, because you can find all hookable methods in ProcessWire simply by doing a search for 3 underscores "___". A recursive grep is one easy way to accomplish that. Page::render() is actually a very unique case that you won't see elsewhere in PW (that I can think of). Usually I would have just put a method like that directly in a class and have it handle the render from there (or have the method there to call up the PageRender module). But PW started out as fully API driven, where there was no such thing as "render" of anything, to the core. So the ability to "render" anything was seen as something specific to the web context of a CMS. That's ProcessWire now, but its roots are pure CMF. Today, I would likely just put that render() method directly in the Page class. But I also don't see any reason to move what's already working there, as it really makes no difference in how it works. And you can still hook Page::render if you want to, just like it actually did exist in the Page class. Because you can't actually see a Page::render() method in the class, we use phpdoc at the top of the file for it. I would love to make everything hookable, but the reality is that there is a little overhead associated with every hook (in any hook system). So I don't usually make methods hookable unless there is a request for it to be. We started with very few hooks, and now we have quite a lot. But the majority of the hookable methods you see in PW today are the result of people asking for them to be hookable. And luckily, it's very easy to do just that: just append 3 underscores, and you are done. I would answer this pretty much the same way as the Hookability point above. When more granularity is needed somewhere, we add it, and there's lots of examples throughout the core. But it's hard to know where one might need that until it is asked for somewhere specific. When a module like ProcessPageEdit was originally written, I honestly didn't know if anyone would ever want to hook anything in it at all. Over time, it has become more granular, and over more time will become even more so I'm sure, but only when specific needs for granularity/hooks come up. I love flexibility, but I also love efficiency. If everything in ProcessWire was fully granular and hookable PW might be very flexible for someone looking to hook specific things, but it would also be bloated and slow. My preference is to make specific things more granular and hookable when it will solve someone's specific need. Granted, there are plenty of hooks in PW already that nobody is using, but they are generally in places where it makes no difference in terms of efficiency. I'm not suggesting that hooks aren't efficient – there's very little overhead from hooks. It's just that if you multiply a very little overhead over thousands or hundreds of thousands of calls, then it becomes something. Are there any examples? I've tried to cover all potentially useful state changes with hooks, even if they aren't actively used. For instance, see the large set of hookable methods at the bottom of the Pages class. You'll see similarly named methods in any core class that deals with state changes (like Fields and Templates for example). Though it's also possible I've misunderstood what you mean.1 point
-
Interesting discussion! For me (as a developer), the advantages of ProcessWire's hooking system overweight the issues you mentioned. I agree, it's sometimes harder to find the relevant piece of code, because it gets added dynamically with hooks. Debugging is definitely harder too. But in my opinion you can never achieve the same flexibility with events. For example, how would you handle the beforeHooks, which are executed before the "real" method is invoked? How would you modify the passed arguments? Also the afterHook can modify the return value. It's so powerful and easy to do - just add those three little underscores and you can use this power in your own Wire-derived classes. I like1 point
-
Interesting topic, thanks for your efforts accumulating all those infos. Although I've yet to investigate further the alternatives you are proposing, there are a couple of things that come to my mind regarding this: When it comes to debugging hooked methods, I totally feel you. It can make you pull your hair sometimes. But the thing is, you can either have massive flexibility and power in this case, and then have to trade in some other things. It's like with loosely types languages vs. strongly typed languages. Loosely typed languages give you great power, but it can be a pain, for let's say a Java developer. Two things I've used heavily in the past half year or so, that saved me a lot from going bald: The ChromePhpLogger module by soma, it's not an ideal debugging tool on it's own, but certainly a necessary one in my toolbox Unit tests: I've learned to split my logic into pieces as tiny as possible. During development I only test against those tiny pieces. If the pieces are working on their own, the big picture code will mostly work out of the box. Debugging also only happens on the tiny piece level and makes massive backtrace debugging madness almost vanish1 point
-
Hey BitPoet, thanks a lot for your answer. Probably you're right and this is the most-straightforward solution to the problem. I'll just go and and try to get it working. Will definitely publish my solution for the PagePathModule here, maybe it can be helpful for someone (or merged into core). With kind regards Marc1 point
-
When you're in charge of a large production setup, updates require planning, work, and may cause both issues and downtime, which is a huge no-no for the people (and/or services) relying on you. Everyone expects to get the latest and greatest stuff, but they're rarely willing to accept that it comes at a price. The whole point of LTS versions is that you don't have to be constantly updating your machines. It gives you peace of mind and your services much-needed stability.. and, of course, it helps keep your costs at a sustainable level You could always skip the version of any application provided by the OS package manager, but not everyone likes to do that, as it a) makes things more complicated, b) requires extra work and c) means you'll be ditching the benefits of your LTS OS for that particular application. I for one don't particularly enjoy working with old versions, but in some cases I've learned to acknowledge that it's a necessity.1 point
-
Seeing that Page::set isn't hookable, my best bet would be to store the "name{$language->id}" values away in a hook after Page::loaded and compare them after Pages::save.1 point
-
This is my first site I made for a client with PW: http://www.springbeestjes.be It is a simple online shop used (for the moment) PayPal. It is expandable for the future. Modules: - Maintenance module http://modules.processwire.com/modules/maintenance-mode/ I want to thank all the PW-people who helped me learning and understanding PW, also for the fast and good support. I like this CMS!!! Now I preparing the next project Regards, Christophe1 point
-
I think PageRenameOptions should be able to help you out - just use the "Prevent Manual Changes" option. Or, you could make use of Martijn's AdminCustomFiles to insert this JS (which is what PageRenameOptions uses): $(document).ready(function() { $('.InputfieldPageName input').attr("readonly", "readonly"); }); You would attach it to: ProcessPageEdit1 point
-
Late to the party (as always), but anyway: if you're thinking about static site generators, I have always found that they are limiting in one way or another. A lot of them are “blog-aware”, which translates to “anything that is similar to a blog will be built quickly, everything else will take hours and be painful”. Just my experience with them. A nice alternative is assemble, because it does (much like PW) give you a lot of freedom to work the way you like to work. It's basically a Grunt plugin which generates static HTML from Handlebars templates. It's kind of clumsy to do certain things (like i.e. building navigations dynamically) and they're apparently in the middle of rewriting the whole damn thing (for quite some time now), but if all you need is a small template system to be able to use variables, partials/includes and layouts in HTML, it's worth a shot.1 point
-
This error means, that there is somewhere some field, which has two entries with the same id, but the id should be unique. In your case this id is "41-0". FieldtypeMulti means it has to be a multi value field. In my cases it's mostly the fault of some custom module, but could be anything else, too.1 point
-
Slight update (sorry if this is a monologue!) I was quite comfortable building out the static site in Middleman, although I did find the documentation extremely disappointing, for a seemingly well-backed product there isn't a great deal of meat beneath the gravy docs-wise. I started to consider looking at one of the paid products (Kirby / Statamic), they both seemed to be very solid, had good documentation and had the bonus of being a "full" CMS despite being NoDB. In the end I decided to go with Statamic for a few reasons. I was extremely impressed with their docs. The simple admin area is very nicely put together and pretty intuitive. So far I pretty much have the project coded up and have come across some really nice features (some that PW may learn from - as per the original post by Diogo ) Others aren't really relevant as Statamic and PW do cater to different sorts of sites. I doubt it will be used for more complicated database-driven sites, that said, what I do like about it: 1. Configuration through YAML - Have to say this is proving to be a real hit for me. Set global variables, decide which fields to show for any given template in the admin 2. Being able to add content through files - I personally haven't made a great deal of use of this yet as I still prefer adding content through an interface at this stage. Despite this I can see the appeal, especially to people who use MarkDown a lot. 3. NoDB, easier site synchronizing/backups - OK so this is an obvious one but clearly having no database is an advantage when it comes to Zipping a site up or keeping two copies in sync. 4. Templating syntax - This is controversial, not least to myself. I wholeheartedly agree with Ryan's appraisal on using PHP syntax in PW. That said, there's no arguing that when we're using a simpler system for a simpler site, there's something pleasant about being able to leave out some of the less glamorous parts of writing PHP ( ; {} [] ). My preference for tenplating engines over pure PHP completely depends on the aesthetics of the engine syntax. In Statamic's case it is elegant so a plus point for me {{ title }} 5. Variable modifiers - Sort of an extension of 4 really but again when we're keeping things simple it is nice to be able to call on some nice simple helpers that enabe us to write less code. http://statamic.com/learn/templating/variable-modifiers --- Clearly there are things here that are good because it makes a nice change from coding in a more complex site development process (as I often do with PW), maybe of things that PW could one day use, perhaps some way of writing more code in the editor than clicks in the admin, although that must be limited by the database interactions that must be necessary. I still don't think there is a system out there that can touch PW when it comes to a tool that can accomplish almost anything in an organised, lean and powerful way.1 point
-
1 point
-
I'm currently thinking about how to manage achieving something like craft's "Live-Preview" feature in processwire. Having this would be so awesome1 point