-
Posts
17,231 -
Joined
-
Days Won
1,697
Everything posted by ryan
-
Module: Languages (multi language content management)
ryan replied to Oliver's topic in Modules/Plugins
I didn't realize that you also added a languages API var, sorry for the duplication there. The new $languages API var can also be hooked in many ways, and I'll be glad to add anything to it that would be helpful to you–just let me know. The $languages API var is extended from this class, which is the same one used by users, roles, permissions, etc. This class: /wire/modules/LanguageSupport/Languages.php Extends this class: /wire/core/PagesType.php Each of the languages is actually just Page. If you iterate the $languages API var, you can get all the language pages. There is also $languages->get(...) and $languages->find(...) that function just like the ones from the $pages API var. I'm not sure that I have enough background on your module to answer that. But did want to mention that the new LanguageSupport module adds a template called 'language' that is used by each Language Page. You can add fields to that template like any other. So if you were to utilize the PW 2.2 languages with your own, then I'm guessing you would likely add the fields to that 'language' template that your module needs, and then they would be available in all the languages. Again, I'm not sure if this is the right strategy for your module or not, but just wanted to mention that is one of the ways it can built upon. It is. The $languages API var can be extended like anything else. If you wanted to add new functions to it, then you would just add a hook for a function that isn't already there. i.e. <?php wire('languages')->addHook('languagesNewMethodName', $this, 'thisClassMethodName'); …or… <?php $this->addHook('Languages::newMethodName', $this, 'thisClassMethodName'); I'm happy to modify or add anything necessary to support the needs of your module – just let me know of any way I can collaborate or be of help. -
Remaining the /processwire/ page is always a good idea, especially if your client is prone to using insecure passwords with their accounts. When you first rename it, note that you may get a 404 after saving it. That's okay–it's expected since the admin moved. Just navigate back to your new admin location.
-
Edit your /site/config.php and change the line that has $config->debug = false; to be true. Then you may get something more descriptive than a 500 error. Check that the /.htaccess file is there, and is the correct one for ProcessWire. Very often when migrating a site, it's easy to miss the .htaccess file and end up with one that was previously on the server. This is the first thing I would check. You mentioned that your index page works? Are you seeing the proper homepage for your site? If so, that's good and that would rule out a database issue. Are you able to access /processwire/ ?
-
Another way you can go is to use page reference fields. Add two new 'Page' reference fields: topnav and footnav. Make them support multiple pages. Don't restrict it to a parent or template. Select 'PageListSelectMultiple' as the Inputfield for them. Save, and add them to your Homepage template. Now edit your homepage. For the 'topnav' field, select all the pages you want as part of your top navigation, and for the 'footnav' field select all the pages that should appear in your footer navigation. Drag to sort them in the order you want. Edit your main markup file (or head/foot includes) and use the following code to output that navigation: <?php foreach($pages->get("/")->topnav as $item) { echo "<li><a href='{$item->url}'>{$item->title}</a></li>"; } …repeat the same for the footer nav, except iterate the footnav (rather than topnav) field. In the sites that I develop, I almost always have the footer nav hard coded in the main markup file (I don't usually need it to be dynamic). For when I need the topnav dynamic, I'm usually sticking to the site's root level structure for the navigation (iterating the non-hidden children of the homepage). You may need all this stuff to be dynamic, in which case there are a lot of options. But I just wanted to mention that you should only make stuff dynamic that needs to be. When stuff can be hard coded in a template file, it consumes fewer resources. So if you stick to a policy of hard coding stuff that changes rarely and doesn't need to be dynamic, then you'll benefit from better performance, use less energy, save more trees, etc.
-
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
I just committed an update that adds counts of abandoned and blank translations with each file (when applicable). You'll see this if you pull in the latest commit, and a screenshot is also attached. I was worried about the overhead/slowness of parsing all those files on every page load. However, I went ahead and tested it anyway. I was surprised not to see any apparent slowdown – it seems quite fast. It is doing some heavy lifting, but apparently not the scale of issue that I thought. Maybe that will change once we get lots more files in there, but for the moment it seems to be fine. Let me know if you experience something different. I will probably add a caching mechanism if it becomes slow. -
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
I definitely like the idea, but don't think I could make it scalable from a development standpoint. It's a rather heavyweight process to parse all the files to detect these things. Once we get to having a hundred translation files in there, I don't think everyone would want to wait 20 seconds for it to parse everything every time the language page loads. I may have to take a LazyCron approach with this to let it do the heavy lifting behind the scenes when you aren't looking. I will plan to do this. I may not be able to cover 100% of everything (like getModuleInfo title/summary fields), but will find out as I do it. My favorite Finnish city today is Turku I watched a TV show last night about the big ships they build there at the Aker (STX) shipyard, amazing projects! -
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
Whenever you click 'edit' for a translation file, it identifies any translations that are no longer current at the top. It refers to them as 'Abandoned Translations' because the original English translation has changed. See the attached screenshot for an example of what I mean. It shows that the original field that was previously worded "Hello, how are you doing?", has been changed to "Greetings, how are you doing?". The field has been blanked, and the translation has been moved to become an Abandoned Translation. We can't make guesses about the scope of the change, so the system has to abandon the translation and let the translator decide what to do with it. The translator may decide that the change is insignificant, and they can just copy/paste their abandoned translation back into the field. Or they may decide to delete the abandoned translation and perform an entirely new translation. If new phrases are added that weren't previously there, then they just show up as new/blank fields to be translated. I maybe able to call these out in some way more prominently too. -
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
Darn, I thought you'd found it. And I think you have, but looks like we can't take advantage of it just yet. At least not with that particular option. It sounds like most agree that it's best to provide the option for everything to be translatable, but don't require everything to be translated. That's pretty much the way it's setup now, except that I haven't yet made those other modules translatable... I will plan to do it. I want to mention that PW doesn't actually require any language files to run. The language in the code is assumed to be English, and the phrases that appear in the code are the English translation. Those English translations are hashed (md5) and then serve as the tokens for all other translations. So it's reasonably easy for us to make something translatable, even if there aren't any translations available for it. The English language you see in the Languages list right now is actually just a placeholder for the language already present in the code. But you could make your own English translation (if you wanted to) just by adding files to it. The good news is that it really doesn't make module development more difficult. The essence of it is that you just have to wrap your text phrases in a function call, so that $value = "text"; becomes: $value = $this->_("text"); The Wordpress i18n documentation will be our starting point for the documentation (assuming it's open source, I think it is) and I'll modify it to be ProcessWire specific and call out any differences. Once your module is sending its text through $this->_('text'), if you want to add a translation to another language, you just go to Setup > Languages > [any language] > files > new, and then type in the path to the file. I'm guessing that some module developers will choose to include json translation files of their module, and some won't. For those that do, one would just upload that json file to their target language in PW and the given module would translate. -
Looking good Soma! Just made those changed and tested it out. Very cool. A couple things I found: It reported 0 results for me until I selected another template, and then changed it again to select 'Show All'– then it worked. In your find() code in the module, you could replace it with this and it would give the same result but be a little faster/more efficient: $pa = $this->pages->find($selector); $total = $pa->getTotal();
-
I think direct access is kind of assumed, just because you'll see it in nearly any code example you come across for ProcessWire. But maybe it wouldn't hurt to add it, as it's only 2 short lines (see below). But I'm happy either way. <?php $value = $page->any_field; // same as $page->get('any_field'); $page->any_field = $value; // same as $page->set('any_field', $value);
-
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
This is great, thanks Jasper! Question for you guys: how far should we take the translations? Do you want the other parts of PW admin included in translations like: Setup > Fields Setup > Templates Setup > Languages Modules Access Or is it better to just keep the basics translated, like the things we would have our clients use? Basically, I want to keep the scope of it small enough that people can add languages really easily. Also want some flexibility to keep adding improvements in the Setup sections without creating work for translators every time I add/update something. But maybe that's just the nature of it. There is potentially a large amount of translatable text, especially in the Setup sections (Fields/Templates). I'm just trying to determine if these parts should be included in the translations or not. -
I agree, I think this looks like a great addon to the datepicker. If anyone is interested in implementing this, please go ahead and let me know how I can help. If not, I will plan to implement as soon as there's time to do it.
-
Thanks, just added my modules to this too.
-
Statestreet, I just realized I didn't have this on GitHub, so I posted it to there, just in case you've got an earlier version. Here is the version that I am currently using on processwire.com for the Twitter feed that appears throughout the site: https://github.com/ryancramerdesign/MarkupTwitterFeed I'm wondering if your PHP might have allow_url_fopen disabled? You can find out by looking at your phpinfo(), i.e. put this on your server in a PHP file (like test.php) and load in your browser: <?php phpinfo(); I am guessing that you might have the allow_url_fopen option disabled, and that would prevent this module from being able to load the RSS feed. If you find that the option is enabled, then next check your Twitter RSS URL. Logout of Twitter and see if it still works? If I recall, some of Twitter's RSS feeds don't work unless you are logged in with the same browser you are retrieving them from, and you may have to enable access to it somewhere in your Twitter settings... it's been awhile since I've looked at this, so not positive what the current deal is there. But something to look at. Please let me know what you find.
-
Looking fantastic Soma!! You went further with the number of items hidden in 'advanced' than I was originally thinking, but now that I see it, I like it, and it makes sense. Creating, modifying and saving items really is more of an advanced thing, so I think your selection of what should go where is very well crafted. When in 'simple' mode: what do you think about all the sections that have advanced items ending with a tiny 'more' link or something like that? That way, one could look at all the $page options (for instance) without expanding all the advanced options for everything else. It would also make it clear that there is more depth to the cheatsheet for someone that might miss, or not understand what the 'advanced' option is at the top. I'm thinking these options below might fit better under 'advanced'? $page $page->next; (because one has to be careful with next/prev and large groups of pages) $page->prev; $page->next(); $page->prev(); $page->setOutputFormatting(); WireArray $a->getArray() (because rarely used) $a->getKeys() $a->getValues() Selectors: start=n (used more by system than user) end=n (rarely used) include=all include=hidden check_access=0 children.count=n created=timestamp (because these were advanced in $page section) modified=timestamp created_users_id=int modified_users_id=int $user $user->pass (because only useful for setting value) $input $input->get["name"] (because no need to list 3 ways of same thing in 'simple' mode) $input->post["name"] $input->cookie["name"] $session $session->getAll() (because rarely used) Lastly, what do you think about having the direct access get/set mentioned in $page like it is in $session? Maybe people already assume this, but I wasn't sure. $session->$name = $value $value = $session->$name
-
Thanks Soma, I tried to install and test this. While I can't get the module itself to work yet (getting some errors) I am seeing the proper load order for it's js file when viewing the 'data tables' page and looking at the source. I am wondering if this module ever had autoload enabled? The autoload setting in PW's modules table will be according to what it was at the time of installation. So if it was autoload at one time and you changed it, PW might not realize it's no longer autoload. If you view the modules table in the DB (via PhpMyAdmin) or the like, and locate the ProcessDataTable in there, what does it have for the 'flags' column? It should be a '1'. If it's a '2' or a '3', then it's autoload. If that's the case, try changing it to a '1' manually, or just uninstall and re-install the module from PW admin. Let me know what you find here...
-
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
You caught me! ;D Just checked, and you are right it looks like the files do not show as UTF-8 when I load them in my text editor (mine show Mac OS roman encoding). I don't really know why because they are saved with nothing but PHP's file_get_contents() and the data in there is UTF-8. I'm guessing the file has no explicit encoding and it's just showing up as whatever is one's editor default (?). I suppose it doesn't really matter if one doesn't need to load the JSON file in a separate editor, but would like them to be explicit about the encoding if possible–just not yet sure how. The only thing I can find in the file_put_contents user comments at php.net (for "utf") is this: <?php $myFile = 'test.txt'; $myContent = 'I love PHP'; file_put_contents($myFile, utf8_encode($myContent)); But that doesn't really help us, because utf8_encode() is for converting ISO-8859-1 encoding to UTF-8, and we're dealing with text that is already UTF-8 encoded. -
If I understand correctly, you want the code snippet you pasted to appear at some place in your bodycopy that you designated. This is something that I do regularly with both images and fields. I tell the client to type either the word "images" or "files" in it's own paragraph with nothing else, and then all of their files or images will appear there in the right order with description, etc.. Here's the code I use to do it: <?php function bodytext($text, $page) { if(strpos($text, '<p>files</p>') !== false) { $out = ''; foreach($page->files as $file) { $out .= "<p><a class='file file_{$file->ext}' href='{$file->url}'>{$file->description}</a></p>"; } $text = str_replace('<p>files</p>', $out, $text); } if(strpos($text, '<p>images</p>') !== false) { $out = ''; foreach($page->images as $image) { // make the image small enough to fit bodycopy column, if it's too big if($image->width > 500) $image = $image->width(500); $out .= "<p><img src='{$image->url}' alt='{$image->description}' /><br />{$image->description}</p>"; } $text = str_replace('<p>images</p>', $out, $text); } return $text; } ?> <!-- later on in your code when you output the bodycopy --> <div id='bodycopy'> <?php echo bodytext($page->body, $page); ?> </div> I've done this on a couple sites now, and am thinking I should just make it a Textformatter plugin or something.
-
I've tried to duplicate here this morning, but still can't. Can you tell me if I'm missing any parts necessary to duplicate? Here's what I did: Copy the code you pasted to create ProcessDataTable.module, and also created an associated ProcessDataTable.js file with this: $(document).ready(function() { alert('test'); }); Then I put those two files in this directory: /site/modules/ProcessDataTable/ I installed from the Modules menu. Then I went and created this page in the admin: /processwire/test/. I select ProcessDataTable for the 'process' field of that page and save. Now I have a 'test' menu item in my admin top nav. If I click that page, I get the test alert. If I view the source, I see ProcessDataTable.js loading after JqueryCore and JqueryUI, as they are supposed to. Are there any parts I'm missing? For instance, I'm using the default admin theme. Do I need to install a different admin theme to duplicate? Is it possible there is some other autoload module calling upon ProcessDataTable in your case? Thanks, Ryan
-
There are a way to do it with TinyMCE only (using styleselect in the buttons1, using theme_advanced_styles and modifying TinyMCE content.css), but I think it's simpler just to apply it at render time in ProcessWire, like this: $page->body = str_replace("<pre>", "<pre class='brush: js'>", $page->body); You could do that before outputting your $page->body field.
-
Creating your own login template is a pretty simple thing. I recommend creating a template called "login" and putting the following in it: <?php // $out is where we'll keep our output $out = ''; // $form is where we'll keep our custom login form $form = " <form action='./' method='post'> <p><label>Username <input type='text' name='user' /></label></p> <p><label>Password <input type='password' name='pass' /></label></p> <p><input type='submit' name='submit_login' value='Login' /></p> </form>"; if($user->isLoggedin()) { // user is already logged in if($input->get->logout) { // page was accessed with ?logout=1 GET variable, so log them out $session->logout(); $session->redirect('./'); } else { // tell them they are logged in and how to logout $out = "<p>You are logged in. <a href='./?logout=1'>Logout?</a></p>"; } } else if($input->post->user && $input->post->pass) { // user submitted the login form if($session->login($input->post->user, $input->post->pass)) { // user was authenticated and logged in $session->redirect('./'); // or redirect to your members-only page } else { // the login failed $out = "<p class='error'>Login failed</p>"; $out .= $form; } } else { // user arrived at login page for first time $out = $form; } include("./head.inc"); // your site header, if applicable echo $out; include("./foot.inc"); // your site footer, if applicable Then assign the above template to your page, and you are set. Another approach you can take is to use PW's existing ProcessLogin module (the same one used by the admin). This takes less code as PW handles creation of the login form and the login logic. But you'll have to use and style PW's login form rather than your own. Here's how to create a template using PW's ProcessLogin module: <?php $out = ''; if($user->isLoggedin()) { // user is already logged in if($input->get->logout) { // user asked to logout – logout request via URL: ./?logout=1 $session->logout(); $out = "<p>You have logged out</p>"; } else { // user is logged in, give them a message or redirect them $out = "<p>You are logged in. <a href='./?logout=1'>Logout?</a></p>"; // or redirect them to your members-only page: $session->redirect('/path/to/page/'); } } else { // user is not logged in. present the login form from ProcessLogin module, // along with any system notices to accompany the process. $process = $modules->get('ProcessLogin'); foreach(wire('notices') as $notice) $out .= "<p>{$notice->text}</p>"; $out .= $process->execute(); } include("./head.inc"); // your site header, if applicable echo $out; include("./foot.inc"); // your site footer, if applicable
-
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
Slkwrm, Diogo–nice work! Just tried out both and they work great. Thank you for all of your efforts in doing these translations. I must say, Russian is another very cool looking language to me, perhaps because it's so completely different from English (no landmarks for an English reader at least). The only time I saw Russian language as a kid was watching/reading about space programs, nuclear submarines, etc. So it brings me back to that when I see it in ProcessWire–fun and cool to see. Are you saying that you want to use an encoding other than UTF-8? I think that UTF-8 is the only encoding that will let us be language neutral in ProcessWire itself. But any tool that will let you change the encoding of a text file should let you convert to and from it from the JSON files. For instance, on OS X, I use a tool called TextWrangler (free version of BBEdit) that lets me convert a file from one encoding to another pretty easily. Just be sure to convert back to UTF-8 before putting in ProcessWire. Are there any Cyrillic symbols that you aren't able to use in PW/UTF-8? -
Sounds good, let us know how it goes. I'm suspicious they are using eval() since they've changed the PHP tags (almost certain of it), so it may slow things down in PW a lot, but give it a try and let us know how it works.
-
Just to confirm, the code snippet you posted is reproducible with it's JS loading before jQueryCore? I will give a try here and get a fix going next week. In the short term, I'd suggest renaming your JS file, and instead loading it like this: <?php public function ___execute() { $this->config->scripts->add($this->config->urls->ProcessDataTable . 'your-js-file.js'); // .. then your code here } I'm hoping that might provide a temporary fix in your case, but since I don't yet understand why it's loading jQueryCore after yours, I can't say for certain. But I am certain we'll be able to find a fix next week.
-
Soma–sounds good. I'll plan on adding the appropriate hook in ProcessPageList next week in the dev branch, and we can do more testing then.