Leaderboard
Popular Content
Showing content with the highest reputation on 06/24/2015 in all areas
-
Sounds interesting. Here's one way you can do it: $table = $fields->get('your_page_field')->getTable(); $query = $database->query("SELECT data FROM $table GROUP BY data"); $ids = $query->fetchAll(PDO::FETCH_COLUMN); $items = $pages->getById($ids); // $items is a PageArray echo $items->implode("\n", "<a href='{url}'>{title}</a>"); If we were to add this to the API, I think I'd want to make it accessible from a regular find() selector, rather than as a separate findSelectedPages method. That way it could be used with things like InputfieldSelector. Perhaps something like this: $pages->find("your_page_field=:selected"); ...where ":selected" is a keyword is would recognize to execute this behavior.6 points
-
This is the sequence of code that gets executed before that error: $dir = wire('config')->uploadTmpDir;if(!$dir || !is_writable($dir)) $dir = ini_get('upload_tmp_dir'); if(!$dir || !is_writable($dir)) $dir = sys_get_temp_dir(); if(!$dir || !is_writable($dir)) throw new WireException("Error writing to $dir. Please define \$config->uploadTmpDir and ensure it is writable."); I don't think the trailing slash matters here, unless that causes Windows to return the wrong permissions for the directory (?). My best guess is that the values returned by both your PHP upload_tmp_dir and sys_get_temp_dir() are not writable or don't exist. Manually specifying the $config->uploadTmpDir would be the best course of action here.2 points
-
If you have a Template but no associated template file Copy basic-page.php or home.php from your /site/templates directory to your computer Rename the copied file to news.php Copy news.php to your /site/templates directory.2 points
-
There is quite a lot of WP bashing going on here in the forums. I can totally understand the reasons for that and agree with most of what is being said. What I don't understand is why people feel the need to go into this over and over again. No offense intended here. I think that in the long run people who responsibly build and maintain websites will eventually move away from WP to other platforms like PW. I introduced PW to an agency that I'm freelancing for and since then they started to do most of their projects with PW. Seeing the fast growing PW community also indicates that people are able to make choices based on their experience with other platforms and what they see can be achieved with PW. From an energetic point of view it is preferable not to put your energy into something that you don't want or like. Any energy that we put into those things will most likely help to support them even if we don't intend to do so. So I just leave WP be what it is and concentrate on all the wonderful things that I can do with PW2 points
-
In the last few weeks I've notices some request (e.g. here and here) to be able to get pages based on if they are selected in page fields of other pages. I think adding a method for this would be a nice addition to ProcessWire, as it's often the case that the pages itself are options we just want to get, if they are used somewhere. Currently the task "Get all tags used by some blogposts" has to be done manually like this: $tags = $pages->find("template=tags"); foreach($tags as $tag){ // Filter unavailable if(! $pages->count("template=posts, tags=$tag") ) continue; // Do stuff with it } Now it would be nice to have something like this, where we don't need to have a selector for tags (this is done by the pagefield already). // Find all pages, which are selected in the "tags" field of the selected posts $available_tags = $pages->findSelectedPages("template=posts", "tags"); I'm not that big a MySQL guy, but I can imagine this not only improving readability, but also reducing database calls.1 point
-
Very insightful discussion and one that I've thought of deeply as well. One other approach that's easy and built directly into CKEditor is to simply use the Content Templates plugin. The plugin already comes with ProcessWire's CKEditor, so simply enable it by editing your CKEditor field and allowing the option in the "CKEditor Toolbar" field. I put some screenshots indicating exactly what to do below. I'm exploring this approach right now so I don't have much insight yet. https://goo.gl/kbtDTG https://goo.gl/a4JBAH1 point
-
That's most likely because a file field does not handle thumbnails, which is special to images.1 point
-
For the YouTube videos you may want to look at the following modules: http://modules.processwire.com/modules/textformatter-video-embed/ http://modules.processwire.com/modules/process-get-video-thumbs/1 point
-
Any screenshot to see, so we can properly tell what could be the issue, but as long as it imports then you should be seeing your content, screenshot please ?1 point
-
Hi zervis and welcome! You say that the importing works fine, so I don't think it is an issue with MigratorWordpress. If you don't have a view link, then it sounds like you don't have a template file for the new pages - something like news.php in your templates directory. Sorry, I am in a rush here - it's late and I am headed on vacation for two weeks in the a few hours, so hopefully someone else can help guide you through the process of creating the required template file if you are not already familiar with that - it's just like any of the other template files - basic-page.php, home.php etc.1 point
-
Luckily I do not have to work with WP sites, as I'm also build very less sites, mostly private things. There is only one site that was built with WP, it's a private site for my son and me. We haven't made any updates to it since two years. And I want to port it to PW since I know PW, but haven't found the time until now. My 10 years old son has made some photos that he wants to see on the homepage there and I need to remember where the admin / backend / login page was. I tried some URLs that all fail. Than I opened a FTP client and looked to the directory structure and found the name of the subfolder which contains the wp-admin folder. After typing this URL and failing again I got a bit dazzled and was talking / grumbling to myself. My son began to laugh and rolling over the floor and shouts: "You are not able to write wp-admin you have written pw-admin. Everything you can think of is PW!". And he is right: after finding PW, I just want to wipe out any past memory regarding WP. After porting this site I can fullfill this to 100%. Until then I have to live with mistakes like pw-admin.1 point
-
I like the "increase memory limit" part the best Btw here's an Advanced WordPress Development Checklist: DONT1 point
-
Hi, the error in your first screen advices you to define $config->uploadTmpDir (in site/config.php) and ensure that it is writeable. So, I don't know MAMP and how it manages things, but I would simply try to find a place for uploads by try and error if there are no useful docs for Windows. For example you can try to create C:\MAMP\htdocs\tmp, and set this in your site/config.php $config->uploadTmpDir = 'c:/mamp/htdocs/tmp/'; // yes, you can use forward slashes, PHP and Apache on Windows converts this internally where needed, also try with trailing slash first! And if this doesn't work, go to that folder with the windows explorer and set it rigths to writeable for everyone as a quick and dirty test. Than try again. If this doesn't help come back here and tell us. (missing trailing slash for the directory ?) You may also try $config->uploadTmpDir = 'c:/windows/tmp/'; // traing slash !!1 point
-
The default MAMP document root (at least for MAMP) is "C:\mamp\htdocs" unless you have changed it in the preferences. That is where your HTML/PHP and image files are stored. The MAMP Pro docs talk about being installed in /Applications/Mamp (how that actually works in Windows is not defined or detailed anywhere I could see). Unfortunately, the MAMP PRO documentation is very Mac specific and it does not talk much about the configuration differences on the Windows version. It's very hard to help you with this when the MAMP PRO docs aren't very helpful. You may also want to ensure that you are using the latest version (3.0.9 Release Candidate 1). You obviously have MAMP Pro working, so the next question would be where is your document root pointed to?1 point
-
Thank you horst, this is exactly what I was looking for. For those interested, this is my working module below, which adds in icons based on an select options field. <?php class DynamicIcons extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Dynamic icons for the page tree based on field values', 'version' => 1, 'summary' => 'Module to change the icon on the page tree depending on field values.', 'singular' => true, 'autoload' => true, ); } public function init() { $this->addHookAfter('ProcessPageListRender::getPageLabel', $this, 'addPageListLabelItems'); } public function addPageListLabelItems($event) { $page = $event->arguments('page'); $page->of(false); // Check options field for correct value if($page->content_type == '1') { // Add fontawesomeicon $styleItem = "<i class=\"fa fa-file-text-o\"></i>"; // Add to pagetree $event->return = $styleItem . $event->return; } } } (This just shows one options but obviously you could add in additional icons for different field values)1 point
-
Another major new feature! I have added an Export to CSV mode which generates a CSV file containing the fields for all child pages. It currently supports most field types, including: Text/Textarea/Integer/Date fields Page fields - exports the "Title" if available, or "Name" if not (eg user template), rather than just the page ID File/Images - exports the filenames Profields Textareas - automatically converts field into multiple columns - one for each subfield Profields Multiplier - separates values with a customizable separator - you can choose a line break if you want which is nice when opening the CSV in Excel. This same customizable separator is available for other multiple fields like Page fields, File/Image etc It does not support Profields Table, PageTable or Repeaters as these would get very messy. Note if you want to provide an export for specific Table fields, don't forget to check out: Table CSV Import/Export Fields to be exported can be predefined or customized by the user. Also includes an API export method: //export as CSV if csv_export=1 is in url if($input->get->csv_export==1){ $modules->get('ProcessChildrenCsvExport'); //load helper module //delimiter, enclosure, file extension, names in first row, multiple field separator, array of field names $page->exportCsv(',', '"', 'csv', true, "\r", array('title','images','textarea_test')); //$page->exportCsv() - this version uses the defaults from the module or page specific settings } // display content of template with link to same page with appended csv_export=1 else{ include("./head.inc"); echo "<a href='./?csv_export=1'>Export Table as CSV</a>"; //link to initiate export include("./foot.inc"); } Like the rest of this module, everything is configurable at various levels, so you can include this functionality as a separate tab, or part of the Children tab. You can predefine all settings so the user only has a simple Export button - whatever works best for you. Please let me know how this new functionality works out for you and if you have any suggestions for improvements.1 point
-
Wo and behold, somebody started building that content editor I talked about - separating content from layout: http://madebymany.github.io/sir-trevor-js/ Very interesting! Though I expect the server-side rendering needs to be done with e.g. Node and can't easily be done with PHP.1 point
-
A simple edit link can be done with ease. Regarding in place editing: I think especially for non professionals it's important to make them aware of the fact, that websites don't come in one shape. There are mobile layouts, responsive layouts, maybe a rss feed, which is shown in a rss viewer. Ryan already talked about that earlier in this thread. Nobody wants to have content with 15 " "'s just that the next word flows to the next line. If you just don't like your client to have to leave the current page to edit, take a look at this: http://modules.processwire.com/modules/fredi/.1 point
-
Yeah, I think Sir Trevor is closest what I have seen from open source world as a RTE re-imagined. Looks very promising at least!1 point
-
Thanks for the feedback. Yes I get that users like to see what they get, but you get it when viewing/editing the blocks (click on asm list label name) and on front-end when go preview the page (unpublished pages are viewable by editors). I think it would a small price to pay for blocks in a scalable manner, easy to deal with and sort them. And as said front-end editing is something that should be considered a lot since PW makes it so easy and clients usually like it. I have also mixed feelings and am somehow aware of drawbacks and issues to could lead to. Also misuse of this, either by the developer or by the user. At the end it all comes down to what do you need to solve with this? And does this lead to bad websites/Use of it (I think most of times yes!) Currently I see it like this: My module pros - minimal easy setup - scaleability - reuse fields and blocks (would requires some complex config setup but possible) - blocks are pages - can use repeaters ... cons - no direct inline editing (if a concern at all) - don't see a way to search via simple API selectors (would require special workarounds, a lot of work) - not easy to limit and reuse things, a lot of work would need to be put in module (grows complexity) ... Using repeaters with conditionals (if supported by PW at some point) pros - easily create different repeaters with different types - inline editing - able to use in simple search API selectors (repeater.field) - repeaters are pages ... cons - doesn't scale as good - some larger setup required - not able to reuse fields and sets created in a repeater - dependency on repeaters - can't use repeaters (inside repeaters) ... and not to leave out already possible approach Using child pages pros - straight forward adding them, almost no setup - preview and editing easy possible on front-end - no dependency - reuse fields, template, and content - they are pages ... cons - no inline editing, different approach (but clients usually get this easily) - could interfere with other child pages (although this can be solved if you put them in a global branch and append them using page selects) - needs workaround for searches using API (but easier as they're direct childs) ... somehow After all I'm looking also further and question things like: what about future major features PW maybe introduce and support in future? Import-Export, versioning, drafts etc. Ever thought of that? Currently I don't know where all this leads us. As said this current module only shows a proof of concept and it maybe one possible to further develop. But first I want to make sure it would be the way to go. I think to use pages in some or other way is a good way to go as you benefit from all features a page can have with all it's API, without relying on a new proprietary system. So this is maybe more what's behind it and more technical, but I think I would love to hear other developers to look and think about this.1 point
-
I understand and know this, but why do you need to get the translation when it is just already there. It will output in the language the user views the page ($user->language) This works just fine in the language the user view the page. echo $fields->get("body")->label; Edit: ah, hm it does not? Ok it doesn't get translated as with page fields. Since it's meant to be used for backend context there's no language value for fields settings. So you either use a $lang variable like this: $lang = $user->language->isDefault() ? "" : $user->language->id; // Default needs no id echo $fields->get("body")->get("label$lang"); Or a little hook to add method to the $fields template API var. // from template or a autoload module $fields->addHook("getLabel", null, "getLabelLang"); function getLabelLang($event){ $field = $event->arguments(0); $lang = wire("user")->language->isDefault() ? "" : wire("user")->language->id; $event->return = wire("fields")->get($field)->get("label$lang"); } // now we use it and it will recognize user lang echo $fields->getLabel("body");1 point
-
Greetings, I've spent a lot of time (really, a lot) on the whole subject of front-end editing. It's something that users really want, but I agree with Ryan that we need to make sure it works in the whole scheme of site development. I think it's good to make a distinction between two separate but somewhat similar practices: Front-end editing In-place editing The difference, I like to say, is the idea of "literal" content control. The one that causes trouble is "in-place editing," where clients want to have a window right there on the page in the exact spot where the material appears. They want to create and edit content in that "literal" space. This has many problems. "Front-end editing" is more feasible -- with good development practices. The user can link to an editing function for the page. But they are taken to a proper interface for editing or creating content that takes into account that content cannot always be placed so directly. The interface to edit and create content is not literal. Seen this way, it's up to us as developers to explain to clients what each of these methods is, and why even though one seems prettier it's actually not as good for their sites. It's a few extra steps, but if we design an interface that is easy to understand, users have no problem with the extra steps. Thanks, Matthew1 point
-
I think this is definitely a great idea for a module. But it's also true that it kind of goes against the whole markup agnosticism, and is pretty limited when you consider the broad range of inputs possible with Inputfields. In the context of ProcessWire, it's only a partial input solution. Most importantly, front-end editing goes against content portability and is thus not a best practice. We should be abstracting content away from design, not tightly coupling content into it. I think many using a front-end solution would try to design and fit their content for the space they are typing in. Then the content is a mess when the site goes mobile, responsive or gets redesigned, etc. Promoting content portability is an important job of a CMS, and front-end editing is not good for content portability. That being said, it's great eye candy and there are plenty of cases where I think the benefits of it would outweigh the negatives too. As a core solution, I think front-end editing is a bad idea. But as a modular option for those that want it and understand the tradeoffs, I think it's a great idea. I can think of cases I would use it myself too.1 point
-
That's my code. I always use jquery for instant registration without refreshing page, so my code is composed of 3 parts. The html form, the javascript that performs the validation (also check if username and email are already used) and the php that performs registration process. After registration user will redirect to profile page with welcome message. There are some code lines you probably don't need but you can easily clean...simple php. Note: because of jquery you cannot have the php code inside PW folders so i have an external folder called "process" with all my php files called by jquery at the same level of "site" folder, in this case "/process/register.php". P.S.: i'm using jquery validate plugin for validation. FORM <script type="text/javascript" src="/site/templates/scripts/register.js"></script> <div class="row"> <div class="span16"> <fieldset> <legend></legend> <form action='/iscrizione/' method='post' id="registerform"> <div class="clearfix"><label for="login_name">Username</label><div class="input"><input type="text" id="login_name" name="login_name" value="" maxlength="50" /></div></div> <div class="clearfix"><label for="login_pass">Password</label><div class="input"><input type="password" id="login_pass" name="login_pass" value="" /></div></div> <div class="clearfix"><label for="confirm_pass">Ripeti password</label><div class="input"><input type="password" name="confirm_pass" value="" /></div></div> <div class="clearfix"><label for="email">Email</label><div class="input"><input type="text" name="email" id="email" value="" maxlength="40" /></div></div> <div class="actions"> <input type="submit" value="Iscriviti" class="btn primary" name="register_submit" id="register_submit" /> </div> </form> </fieldset> </div> </div> JS $(document).ready(function(){ $("#registerform").validate({ debug: false, rules: { login_name: { required: true, minlength: 6, remote: "/process/username.php" }, login_pass: { required: true, minlength: 6 }, confirm_pass: { required: true, minlength: 6, equalTo: "#login_pass" }, email: { required: true, email: true, remote: "/process/emails.php" } }, messages: { login_name: { required: "Inserisci il tuo username", minlength: jQuery.format("Inserisci almeno {0} caratteri"), remote: jQuery.validator.format("Lo username {0} non è disponibile.") }, login_pass: { required: "Inserisci la password", minlength: jQuery.format("Inserisci almeno {0} caratteri") }, confirm_pass: { required: "Ripeti la password", minlength: jQuery.format("Inserisci almeno {0} caratteri"), equalTo: "Le password non sono uguali" }, email: { required: true, email: "Inserisci una email valida", remote: jQuery.validator.format("Questa email è già presente nel nostro database.") }, }, submitHandler: function(form) { $("#register_submit").attr('value','Attendi...'); $("#register_submit").attr('disabled', 'disabled'); $.post('/process/register.php', $("#registerform").serialize(), function(data) { if (data=='success'){ var url = "/mioprofilo/"; $(location).attr('href',url); }else{ $(".span16").prepend( $(data).hide().fadeIn('slow') ); $(".error").fadeOut(5000); $("#register_submit").attr('value','Iscriviti'); $("#register_submit").removeAttr('disabled'); } }); } }); }); PHP <?php require_once('../index.php'); require_once('class.tempmail.php'); $input = wire('input'); $sanitizer = wire('sanitizer'); $roles = wire('roles'); if($input->post->register_submit) { $username = $sanitizer->username($input->post->login_name); $pass = $input->post->login_pass; $email = $sanitizer->email($input->post->email); $u = new User(); $u->name = $username; $u->pass = $pass; $u->email = $email; $u->roles->add($roles->get("guest")); $u->roles->add($roles->get("utente-basic")); // my custom role $u->save(); // i add profile picture to every user after registration using 5 different random avatar images. $pnum = rand(0,5); $profilephoto = wire('config')->paths->root."site/templates/styles/images/noprofile".$pnum.".jpg"; $u->profilephoto->add($profilephoto); $u->profilethumb->add($profilephoto); $u->save(); if (wire('session')->login($username, $pass)){ $array_content[]=array("username", $username); $array_content[]=array("login", $username); $array_content[]=array("password", $pass); $admin_id = "noreply@domain.com"; $user_email = $email; sendingemail_phpmailer($array_content, "register.html","class.phpmailer.php","Sitename",$admin_id,$user_email,"Welcome to website"); print "success"; }else{ print '<div class="alert-message error"> <p>Errore durante la registrazione. Riprova.</p> </div>'; } } ?> Code for checking the existing email (or username, same code, just change variable) <?php require_once('../index.php'); $email = trim(strtolower($_REQUEST['email'])); $sql_check=wire('users')->find("email=$email"); if($sql_check<>""){ echo 'false'; }else{ echo 'true'; } ?> And that's the login HTML FORM <?php if ($session->get("_user_id")){ $session->redirect('/'); } ?> <? include('./head.inc'); ?> <div class="topbar"> <div class="fill"> <div class="container"> <h3><a href="/">Sitename</a></h3> <ul class="nav"> <li class="active"><a href="/">Login</a></li> </ul> </div> </div> </div> <br><br><br> <script type="text/javascript" src="/site/templates/scripts/login.js"></script> <div class="container"> <div class="content"> <div class="page-header"> <h1><?php echo $page->title; ?><small> effettua l'accesso</small></h1> </div> <div class="row"> <div class="span16"> <fieldset id="formlogin"> <legend>Login</legend> <form action='/login/' method='post' id="loginform"> <div class="clearfix"><label for="login_name">Username</label><div class="input"><input type="text" name="login_name" value="" class="required" /></div></div> <div class="clearfix"><label for="login_pass">Password</label><div class="input"><input type="password" name="login_pass" value="" class="required" /></div></div> <div class="actions"> <input type="submit" value="Accedi" class="btn primary" name="login_submit" id="login_submit" /> </div> </form> </fieldset> </div> </div> </div> <? include('./foot.inc'); ?> </div> <!-- /container --> </body> </html> JS $(document).ready(function(){ $("#loginform").validate({ debug: false, rules: { login_name: { required: true }, login_pass: { required: true } }, messages: { login_name: "Inserisci il tuo username", login_pass: "Inserisci la password", }, submitHandler: function(form) { $("#login_submit").attr('value','Sto accedendo...'); $("#login_submit").attr('disabled', 'disabled'); $.post('/process/login.php', $("#loginform").serialize(), function(data) { if (data=='success'){ var url = "/"; $(location).attr('href',url); }else{ $(".span16").prepend( $(data).hide().fadeIn('slow') ); $(".error").fadeOut(5000); $("#login_submit").attr('value','Accedi'); $("#login_submit").removeAttr('disabled'); } }); } }); }); PHP <?php require_once('../index.php'); $input = wire('input'); if($input->post->login_submit) { $name = wire('sanitizer')->username($input->post->login_name); $pass = $input->post->login_pass; if(wire('session')->login($name, $pass)){ print 'success'; }else{ print '<div class="alert-message error"> <p>Dati non validi. Riprova</p> </div>'; } } ?> After registration i send a welcome email. That's the tempmail php that use the well known phpmailer class for sending emails adding templating functionality. You need to download the class.phpmailer.php from the web. <? function sendingemail_phpmailer ($var_array,$template,$phpmailer,$FromName,$From,$to,$Subject,$videolist){ if (!is_array($var_array)){ echo "first variable should be an array. ITS NOT !"; exit; } require_once($phpmailer); $mail = new PHPMailer(); $mail->IsSendmail(); // telling the class to use SMTP $mail->Host = ""; // SMTP server $mail->FromName = $FromName; $mail->Sender = $FromName; $mail->From = $From; $mail->AddAddress($to); $mail->Subject = $Subject; $mail->IsHTML(true); $filename = $template; $fd = fopen ($filename, "r"); $mailcontent = fread ($fd, filesize ($filename)); foreach ($var_array as $key=>$value){ $mailcontent = str_replace("%%$value[0]%%", $value[1],$mailcontent ); } $mailcontent = stripslashes($mailcontent); fclose ($fd); $mail->Body=$mailcontent; if(!$mail->Send()){ echo "Errore durante l'invio del messaggio"; exit; } } ?>1 point