-
Posts
17,122 -
Joined
-
Days Won
1,652
Everything posted by ryan
-
I want to add in that ProcessWire does have a pretty nice RSS feed module included in the core. There is a good example of using it in the Blog profile in the posts.php template. I mention it only because it was the first item on your list of things PW doesn't have. As far as the quantity and scope of modules go, that's more an observation about the age of the platform than anything else. Had ProcessWire been open source since the early 2000s then I'm sure you'd find the same depth of modules that you do with the likes of Drupal and WordPress. And I actually think our plugin/module system is far better than theirs too. Growth in the quantity and scope of both free and commercially supported modules is something I would expect to happen with ProcessWire over time, so stay tuned. You've correctly identified some of the major compromises that come with a markup generating CMS like Drupal. I don't like that aspect of it any more than you do. But to the positive points of that approach, I think it gets to the heart of what you are talking about. Something that generates markup is by nature going to be able to provide more ready-to-go, plug-n-play functionality than something that doesn't. The compromise is that you don't have much control over that markup, and the markup is usually a mess. But if it's doing everything else you want, then it still may be worthwhile. As designer/developers we are perfectionists and we take our markup/code as seriously as the visuals, so it's hard to look past the mess and the inherent drawbacks. But you get a nice reward for putting up with this mess, which is lots of bolt-on functionality that you don't have to write any code for. It's a compromise like anything else. Unfortunately I've been unable to keep up with Drupal in my toolbox. I've used it on a couple sites, and have had to continue maintaining them. I was able to get past the wretched smell in the code after a lot of effort. But I absolutely dread doing any kind of administrative task or development task in the system. It's a giant time suck that I really don't like using. At the same time, I recognize that many enjoy using it, and I have a good respect for Drupal and all that is possible with it. So if you've found yourself liking it and it's answering some needs you have, add it to your toolbox (alongside ProcessWire). But only use Drupal when you have to. If you don't want to go very far with code, then I think it's good to keep one markup-generating CMS (like Drupal) in your toolbox for the times when it fits. And only use them when they are going to save real time. Use ProcessWire for everything else. Though for those that like working with code, I wouldn't bother with any markup generating CMS, as I think once you know what you are doing with code, they end up costing, rather than saving time. Also want to bring up the other one you mentioned, Expression Engine. There are some quality add-ons out there for it. If it's doing something that lines up with a given project, go for it. If you are doing work where people pay you for it, the cost of EE and any add-ons should be a non-issue. Your time is worth much more than the cost of these things. You should be passing along the costs of anything you purchase to the client. For me, I can't stand using EE any more than I can Drupal. But if you can stand it, then use it in the situations where it makes sense. EE at least gives you far better markup control than Drupal.
-
You are right--looks like a bug. Thanks for finding it. I've just committed the fix to the source. https://github.com/ryancramerdesign/ProcessWire/commit/af71f46eacb233c03878700a10c685b4042e84c3
-
Create new child as top sibling rather than bottom?
ryan replied to MarcC's topic in General Support
You could also just set it to sort by "date created" (reverse) in the parent's sort setting? This used to be the case up until last month, but is no longer. PW will let you sort by any fields even if they aren't auto-joined. -
When you tried it before, are you sure that you were using $config->paths (not $config->urls)? The $config->paths shouldn't have the "~" in it, whereas the $config->urls should. The reason is that "~" is a virtual directory symbol that is used and interpreted by Apache. But it's not something that actually exists in the file structure, or at least it's not supposed to. Though if you actually have a "~" symbol in your directory path name, then all bets are off as I'm guessing this would confuse not just ProcessWire but Apache too. Based on what Apache uses "~" for, I have a feeling you might have tried to use $config->urls rather than $config->paths. After all, the rest of ProcessWire and all it's modules are already using the $config->paths and $config->urls variables where appropriate. So if there were a problem with using them then I don't think you'd be able to run ProcessWire at all. I have made the change on my system, but need to do some more testing to make sure it doesn't break anything. What we're doing is asking the Page::__isset() function to behave like the Page::has() function, so it's not really the correct behavior for isset to return true just because the field is valid for the page. So I'm thinking of providing a $config var that can be used to override the behavior, rather than just making the change permanent. That way a template engine module like this could customize the behavior towards the need. Thanks for the update! I look forward to taking a closer look.
-
Definitely interested. We do get occasional questions about how to use ProcessWire with some other framework or CMS, and they are running into name conflicts with some and not others. I think most recently I heard Laravel has some class name conflicts with PW, but CodeIgniter doesn't. So I think there would be demand for something that provides a solution to those conflicts. My only worry is if this makes a user's upgrade path difficult, since they are running on a modified version.
-
Best practice for staging to live database synchronization
ryan replied to evanmcd's topic in General Support
Those sound like good options to consider. I wasn't aware of the Phar-archives though am interested and need to take a closer look. But my worry is that anything that tries to bundle everything (including potential large images/files) in one export file to be imported elsewhere is going to run up against scale. I've got a couple sites where the client might have dozens of 12 megapixel photos on a single page. They are pretty unwieldy in size to deal with individually as it is. File-based assets are so unpredictable in size I think I'd be afraid to package them up together in any manner. But packaging up the references, and letting the system transfer them individually will scale well. But it does require that production server can talk to the dev server. -
For that need, I would just modify the existing Comments module. You'll find the sendNotificationEmail() method in FieldtypeComments.module and it's pretty straightforward and easy to modify. Keep a copy of it separately from your installation as well so that you can plug it back into place after doing PW version upgrades.
-
Use Time Machine? Yeah, I know it's a backup solution. But it keeps dated versions, it's automated, and catches the things that I don't think to. It has actually saved me more than any other version control systems. But for more formal version control, I think Git is the best way to go. Lots of guides out there on how to use it. I think it also comes on Macs already. I don't necessarily think it's easy to use, but it's not any more difficult than any of the others.
-
Also make sure you are doing: echo $page->pub_date; rather than just: $page->pub_date;
-
Every site needs a 'root' page (homepage) but it doesn't matter what you do with it. I think all you need to do is just copy whatever is in your index.php file and paste it into the home.php file. And then get rid of your index.php file, because it will be home.php instead. Of course, you can also add/delete fields from the home template as needed.
-
This is intended as an installation profile, so not something that is ready to plug into an existing installation. Though you could certainly copy the templates, install the BlogAPI module, and re-create the fields and pages it uses in an existing install. Though I do plan to make the BlogAPI module installable, so that it can install everything needed by the profile into an existing site. But going to wait till the profile is pretty well nailed down before doing that-- it shouldn't be far off. Also an update about the profile: the next version is going to be running on the Skeleton responsive framework instead. I'm just finding that framework to be a little better for the blog profile. However, I'll still include the Foundation template and CSS file as optional, so that you can still use the Foundation version if you prefer it.
-
Thanks, I didn't realize that, I will update it. I'm not sure I've ever actually seen it written like kB (looks like a mistake doesn't it?) but I'd rather it be correct than pretty.
-
I recommend using either Textile or Markdown if you need to support this type of stuff in your image/file descriptions. For instance, in Markdown you would make bold text **like this** You'll need to run your image/file descriptions through Textile or Markdown before outputting them. So can do that like this. I'll use Markdown in this example since the module is already in the core. $markdown = $modules->get('TextformatterMarkdownExtra'); $description = $page->image->description; // your image description $markdown->format($description); echo "<p><img src='{$page->image->url}' alt='' /> $description</p>"; We'll likely add internal support for these Textformatters for image/file descriptions in the near future, so that you don't have to do the above if you don't want to.
-
I'm not sure I follow 100%, but it sounds to me like the next step you need to take is add the templates in ProcessWire. If your files are already ready-to-go in your /site/templates/ directory, then you can go to Setup > Templates > Add New Template. Check the box next to all the ones you want to add (of course, leave out your header/footer includes since those are partials rather than actual templates). Then create your new pages using those templates you've added as appropriate. How you structure them is up-to-you. ProcessWire gives you a tree structure which you can push in any direction you want to. Think of your pages as a family tree and decide what should be "children" of another. With regard to access control, you can configure this on a per-template basis. You can also leave it off, which will make each page using a given template inherit access control settings from the nearest ancestor page that has a template defining access (often the homepage).
-
Actually I think that the first issue has to do with your MySQL collation. Right now I think it would be utf8_general_ci which sorts (and I think text indexes) as if it were all ASCII, sans accents. This is often desirable, but not in your case. You'd want to change the collation to something like utf8_unicode_ci or a more language-specific version if available (like utf8_swedish_ci). Btw, the "ci" part means "case insensitive". If you want case sensitivity, then you'd want the "cs" version, like utf8_unicode_cs. To change the collation you'd want to edit your database in a tool like PhpMyAdmin. Find the tables for the fields in question: field_title, field_translation, field_definition. Edit the 'data' column of those tables. Change the collation from utf8_general_ci to utf8_unicode_ci. Rebuild the index for each by running a table repair. You can do this in PhpMyAdmin by editing the table, clicking the "operations" tab and clicking the "Repair" link at the bottom. Once you complete this, I think that you should get the behavior you wanted with regard to the matches and sorting. Regarding your second question, I'm a little confused on this one because you are searching for "dom" but wanting it to match "hus"? Obviously that's not possible. But what I think you are wanting is for it to match "dom" by itself rather than in the middle of other words and such... ensuring that your "dom" definition (that contains "hus") comes up a lot sooner than it currently is? If so, you need to use the ~= operator in your search rather than %=. Because %= is a non-indexed (LIKE) search, it'll match terms in the middle of words. Whereas ~= will only match full words. However, ~= is an indexed search and MySQL fulltext indexes only work with words of 4 characters or more by default. But if you have control over your server environment, this is an easy fix to make it support fewer characters. Btw, when you don't specify a "sort=" in your selector, and your selector searches text using either *= or ~=, the sort will be by relevance of the terms searched.
-
Porl, tested out here and seems to work great! Thanks for your work with this. I did run into an error with the paths during installation, though not sure others will as it might have been user error on my part. However, I recommend updating the way reference paths. Don't bother with creating $this->dirname. Instead, do this: // replace this require_once $this->dirname . '/Twig/Autoloader.php'; // with this: require_once $this->config->paths->PageTwig . 'Twig/Autoloader.php'; // replace this $loader = new Twig_Loader_Filesystem($this->dirname . '/../../views/'); // with this $loader = new Twig_Loader_Filesystem($this->config->paths->templates . 'views/'); // replace this array('cache' => $this->dirname . '/../../assets/cache/twig/', // with this array('cache' => $this->config->paths->cache . 'twig/', Also some questions/comments about this: /** * initialises each field of $page. this is overkill but can be used if you don't want to keep * adding individual fields to the controllers. */ function twig_init_fields() { foreach ($pages->fields as $field) { $twig_vars['page']->$field = $page->$field; } } I don't think that your current twig_init_fields() function will work, because the $pages variable is out of scope. Besides, I think you wanted that to be $page instead? If so, you'd want to use wire('page') since $page would also be out of scope in that function. But even if that's the case, I'm confused because when you set $twig_vars['page'] = $page; shouldn't you then be able to already access all the properties of $page? For the same reason, are these lines in twig-test.php even necessary? $twig_vars['page']->body = $page->body; $twig_vars['page']->title = $page->title; It doesn't seem like they should be. But then I tried commenting out the first one for $page->body; and got an error about Page::body() being a non existing function. So it looks like Twig is doing an isset($page['body']); and if it returns false it's trying to call $page->body() as a function. Now it all makes sense. I think I will update the Page::__isset() function to return true when a valid field for the page is requested. That would solve this and prevent you from having to initialize any variables in this manner. And make PW more template-engine friendly, as I'm assuming others may work like this too. Just tried updating Page::__isset() and it does seem to resolve it. Btw, the reason that you wouldn't want to do something like twig_init_fields() is that it would cause all of the page's data to be loaded, regardless of whether it would be used. This would cancel the benefit of PW's on-demand/selective data loading. Your module has me wondering if it wouldn't be a lot simpler for people to use if the Twig parsing happened automatically on the template fields without them having to delegate views, setup $twig_vars, include twigdefaults.php, or call $page->twig->render manually. What if your /site/templates/*.php could just be your Twig views, ready to go? I'm thinking it may be possible with something like this in an autoload module: public function init() { $this->addHookBefore('TemplateFile::render', $this, 'hookRender'); } public function hookBeforeRender($event) { $templateFile = $event->object; $filename = $templateFile->filename; // use some condition to know which templates should use Twig // here we just use filenames that start with "twig_", but might be more elegant to configure which // templates use twig in the module configuration or something if(strpos($filename, 'twig_') !== 0) return; // init twig require_once $this->config->paths->PageTwig . 'Twig/Autoloader.php'; Twig_Autoloader::register(); $loader = new Twig_Loader_Filesystem($this->config->paths->templates); $twig = new Twig_Environment($loader, array('cache' => $this->config->paths->cache . 'twig/', 'auto_reload' => true)); // substitute a pre-defined placeholder file to replace the original template file // so that TemplateFile::render() is actually rendering our placeholder instead: $templateFile->setFilename($this->config->paths->PageTwig . 'placeholder.php'); $templateFile->set('twig_filename', $filename); // original template filename $templateFile->set('twig', $twig); // twig instance } Then the contents of the placeholder template: /site/modules/PageTwig/placeholder.php <?php $twig_vars = Wire::getAllFuel()->getArray(); echo $twig->render($twig_filename, $twig_vars); I haven't tried this yet, but I think it may work. If I get a little more time here in the next day or two to try this stuff rather than just write about it, I'll definitely give it a try unless you get to it first.
-
Best practice for staging to live database synchronization
ryan replied to evanmcd's topic in General Support
From both a security and collaboration standpoint, I have a strong preference for pulling changes where they need to be made, rather than having them pushed from a dev server (export/import). I think you'll like where we plan to go with import/export of field and template data. Especially the copy/paste or file JSON option (which was in PW1 for fields at least), because it doesn't require you to be running a web server to import from. You can develop these things offline on your dev server, then export what you want, take it to your other/live server and paste in the JSON (or upload JSON file) and it re-creates them. PW1 didn't support using the option for modification of existing items (just for creating), but it's certainly feasible to provide the option. When it comes to pages, the same concept applies but is a little more complex given the diverse nature of page data that might include page references, file-based assets and so on. For example, with files/images, we can't reasonably encode those in JSON files and import elsewhere, so the dev server would need to be able to talk with the live server via a web service and pull the assets individually. -
Build Site on Localhost server - How easy to Transfer database
ryan replied to NooseLadder's topic in Getting Started
I always develop in a subdirectory and usually launch to root. While Page Link Abstractor is one way to resolve that, an even simpler way is to do a search/replace on your DB dump file before importing it to your live server/root installation. I use TextWrangler (free version of BBEdit), but any quality plain-text editor should work. So lets say you were developing a site locally in /subdir/ and you wanted to update all the /subdir/ links to be / (root) instead: Search for: ="/subdir/ Replace with: ="/ This should cover all <a> and <img> tags, like <a href="/subdir or <img src="/subdir. -
The LanguagesPageFieldValue (and getLanguageValue function) are only applicable to multi-language fields. The only multi-language fieldtypes there are at present are TextareaLanguage, TextLanguage and PageTitleLanguage. Language alternate fields are an entirely different thing. It is nothing more than one field substituted for the other. For instance, 'image_de' would be substituted for 'image' when the user's language is 'de' and 'image_de' is populated. That's all there is to it. There aren't any other classes or functions to think about behind the scenes with language alternate fields. With language alternate fields 'image' and 'image_de', if you don't want fallback of 'image' to 'image_de' to occur when 'image_de' is populated and the user's language is 'de', then turn off output formatting, or retrieve the value with $page->getUnformatted('image'); Your example was trying to retrieve the value in 'de' regardless of the user's current language. So if that's what you are trying to do, then just access 'image_de' directly, i.e. $img = $page->image_de; or a non-language specific version: $img = $page->get('image_' . $user->language->name);
-
That's correct. But note that these language alternate fields can be used with any fieldtype. So there's not really any reason to use them with TextLanguage, TextareaLanguage or PageTitleLanguage. They are an alternate way of doing multi-language fields.
-
That's great if Twig is keeping track of knowing when to clear cache files. I see no problem with putting them in /assets/cache/twig -- that seems like the best place. I look forward to checking out your implementation!
-
Here's the next version of the Blog Profile. This one incorporates the simpler structure I mentioned earlier, exactly as outlined. Please let me know how it works for you. To install, download a fresh copy of ProcessWire and replace the /site-default/ directory it comes with, with the one in the attached zip: blog-site2.zip Thanks, Ryan
-
Definitely interested--keep it up! Regarding cache, I'm assuming it creates compiled templates and it's the PHP code that it's caching, not the content? If that's the case, there's not much use in trying to hook into PW's cache timing because it's all for output caching. You'd need something that can tell when a template file or template settings have changed and clear the cache then. PW has the ability to store dynamic info with each template, and I think we'd need to keep track of the file modification time for each template file, as well as the template modification time. Then when it sees that the file (or template) modification time is newer than the one saved with the template, it would clear the cache. Not sure how to do it just yet, but think we can figure it out. Let me know if this sounds consistent with what would be needed to you?
-
I have the next version ready. I just need to export the profile and double check it all works. I hope to be able to post it later today after getting through some client work.
-
Best practice for staging to live database synchronization
ryan replied to evanmcd's topic in General Support
Good points. The #1 idea sounds interesting and I like where you are going with that, though I don't think it's safe to consider the meta data independent from the content to the point where it would be safe to version them separately. The recorder modes (#2 & #3) would be great if it weren't for the issue of primary keys you mentioned, but maybe there are places where it could still work. I think that anything that involves merging two versions of the same site has to treat the other's data as totally foreign. Things like IDs have to be thrown out unless you are giving all ID generation authority to one or the other. Personally, I have never seen this as a particular problem to be solved because I've never seen the ability to do it, never expected to be able to, and not sure I could ever trust it if it existed. Nevertheless, I'm enthusiastic about exploring the possibility. But I'd be scared to death of having to provide support for such a feature. Something that I've got a higher comfort level with are specific import/export tools. For instance, a tool that enables me to connect my PW install with another, and browse the fields, templates and pages. Then I can click on "import" and have that field, template or page(s) created on my system too. If there's some matter of meta data to be resolved (like a new page reference with non-existing parent), then I know it then and there and can adjust my import sequence accordingly. If I'm modifying data rather than importing, then I can have the opportunity to see and confirm what's going to happen before it takes place. If we're talking about going between two servers that can't talk to each other, then copy/paste of JSON data from one to the other in the developer's browser is another way to accomplish it. This process seems more supportable because the individual site developer still has some ownership over what's happening.