-
Posts
17,308 -
Joined
-
Days Won
1,725
Everything posted by ryan
-
If you want, feel free to email me the script and I can track it down more easily being able to see it all.
-
Is there a $gig->save(); somewhere? (to make sure the change was saved)
-
The syntax in your second example is correct. When you say it didn't work, can you describe further? Was there an error message?
-
To get it working temporarily, you can set the value of $rootURL in /index.php manually to the correct value: "/racconti-erotici/". But I can see that the problem is that rootPath and DOCUMENT_ROOT are not consistent with each other. They should be referring to the same path, and instead they are referring to different paths. There must be some aliasing going in with the paths at the server side. We've seen this happen in another case, so I think it's something that ProcessWire needs to account for rather than an actual problem at the server. Now to figure out a solution...
-
I just checked and see that I've got a couple of PW2 sites running in subdirs with "-" in them, so I don't think that is it. I'm wondering if you might be running into the same issue as this? http://processwire.com/talk/index.php/topic,46.0.html Though if that were the case, you'd get the same errors whether at a subdir or root... have you tried installation to root in this hosting environment? If you haven't no need to try, but if you can try creating a test.php file with this in it (from that other thread), and posting theresult, I think it may help to reveal what the problem is: <?php $rootPath = dirname(__FILE__); echo "RootPath:".$rootPath."</br>"; if(DIRECTORY_SEPARATOR != '/') $rootPath = str_replace(DIRECTORY_SEPARATOR, '/', $rootPath); echo "NewRootPath:".$rootPath."</br>"; echo "HTTP_HOST:".$_SERVER['HTTP_HOST']."<br/>"; echo "DOCUMENT_ROOT:".$_SERVER['DOCUMENT_ROOT']."<br/>"; $rootURL = isset($_SERVER['HTTP_HOST']) ? substr($rootPath, strlen(rtrim($_SERVER['DOCUMENT_ROOT'], '/'))) . '/' : '/'; echo "RootURL:".$rootURL; ?>
-
That's odd -- does it work in a subdir without the "-" in it? I can't think of any reason why that would be the case, but just wanted to check. Also, what is the context of the hosting environment?
-
$pages->get from a Custom Process module
ryan replied to peterb's topic in Module/Plugin Development
PeterB, Looks great! If you want, you can also delete this part at the top of the class, since those don't appear to be variables that you are using: protected $form; protected $field; protected $id; If you want to make it traverse all levels, making it recursive is easier than you might think. Here's a site map example, which would probably be the same approach you'd want (at least from the recursion aspect): http://processwire.com/api/include/ Also, I wanted to inquire about the context of your individual use. Since it exports data for a Flash site, it seems like you would need to run this Process every time you made an update that you wanted reflected in the flash site? If you wanted it to be dynamic, you could take the contents of your executeExport function and put it into a template and have it echo to the screen (rather than writing to a file). Everything you've written still applies in this case. You would create a new page that uses that template, and name it website.xml. Also, you may want to turn off the trailing URL slash in your template settings, so that it doesn't convert it to yoursite.com/website.xml/". Start your template with a header function like this, so that the client reads it as XML: <?php header("Content-Type: text/xml"); // followed by the contents of your executeExport function This is just an idea on how to expand the utility of the code you've created, but it may or may not be applicable in your case. -
There's a way to do everything. But I'm not sure you want to attempt this in TinyMCE. It may be possible, but I wouldn't take that route unless this is a one time need. Instead, I would just look at it from a markup perspective and figure out what markup it will take to produce that layout. Here is the existing markup pulled from the page you linked to: <div style="float: left; width: 354px; height: 177px;"> <img src="images/10%20Red%20eared%20slider%20copyright%202005%20Pierre%20Fidenci%20-thumb-.jpeg" alt="Red Ear Slider" style="float: right;" height="127" width="192"> <p style="float: left;"><em> Red-Eared Slider <br> (Trachemys scripta elegans).<br> Side view of the <br> head of a Red-eared<br> slider, clearly showing <br> the markings that give<br> the turtle its name.<br> © Pierre Fidenci 2005.</em> </p> </div> <div style="float: right; height: 177px;"> <img src="images/11%20red%20eared%20slider%20copyright%202008%20lisa%20powers.jpeg" alt="Red Ear Slider" style="float: left;" height="127" width="192"> <p style="float: right;"><em> Red-Eared Slider <br> (Trachemys scripta elegans).<br> Juvenile individual, this <br> cute little baby will <br> eventually grow to be the<br> size of a dinner plate.<br> © Lisa Powers 2008.<br></em> </p> </div> To reproduce this in your template, we'll use the same markup and we'll add two image fields to your template called img1 and img2 (though you could also use a multi-image field if you preferred). You will place your image captions in the image description field. You may also want to set your image description field to have multiple rows to better support your captions. <?php $img1 = $page->img1->size(192, 127); $img2 = $page->img2->size(192, 127); ?> <div style="float: left; width: 354px; height: 177px;"> <img src="<?=$img1->url?>" alt="<?=$img1->description?>" style="float: right;"> <p style="float: left;"><em><?=$img1->description?></em></p> </div> <div style="float: right; height: 177px;"> <img src="<?=$img2->url?>" alt="<?=$img2->description?>" style="float: left;"> <p style="float: right;"><em><?=$img2->description?></em></p> </div> Those inline styles would better be placed in a separate css file, but hopefully this is still makes sense. The result produced by the code above would be roughly the same as the markup in the page you linked to. If you need the explicit <br> tags in your image caption (like in the linked markup), you would want to output your image description in your paragraph like: <?php echo nl2br($img1->description); ?> rather than <?=$img1->description?>. However, I think you are better off to let the copy wrap naturally, as the <br> tags are being used for formatting a specific type size (something that you can't always count on).
-
Sorry trying to do this from an iPhone and it's not working so well
-
Adam, You can crop just by using the size() function, and setting the dimension you don't want to change. So to crop the height ,get the existing width to maintain it $w = $page->image->width(); $image = $page->image->size($w, 200); That would Maintain the width but crop the height
-
Adam, The image functions just do resize and crop to center at the moment (more advanced functions coming soon). ProcessWire just uses php for these functions, not a separate script/library. But what I would suggest is to exec() to ImageMagick, which is installed on almost all unix hosting accounts, and will accomplish what you need relatively easily. Let me know how it works out. Thanks, Ryan
-
You can install it at any directory level and it should work just fine. ProcessWire doesn't care if it's in the root, a subdirectory, tertiary directory, etc. You don't need to configure anything for this, as it will pick it up automatically.
-
Also see: /wire/core/Array.php There are lots of different methods in there, most based on jQuery traversal methods. This class is the basis for almost all ProcessWire arrays, including images. I use it for reference all the time. But I am working on getting an online reference for this class and others.
-
Mike, For this example, I'll assume your field is called "images". To get the first image, you would do this: $firstImage = $page->images->first(); To get a numbered index, you would do: $nthImage = $page->images->eq($n); // where $n is a 0-based index Or, of course you can iterate the images too: $n = 0; foreach($page->images as $image) { echo "Image $n - " . $image->url; $n++; }
-
Thanks for posting the fix. I also have an MT gridserver, though not sure I've ever tried to install ProcessWire there recently. Assuming I can reproduce the issue, I will implement a built-in solution.
-
There isn't at present. Mainly because I couldn't think of a situation where you would be echoing someone's email on a public site. But if that's something you need to do, I would suggest iterating the comments field directly (as in the example above), as this is very simple to do and gives you access to every bit of comment data.
-
I've removed the home link from the admin breadcrumbs in the latest commit. https://github.com/ryancramerdesign/ProcessWire/commit/f50cd4ad76cbfc8693ce25b8fec026278d02af46
-
Snippets / chunks / blocks / template inside templates
ryan replied to piranha's topic in Wishlist & Roadmap
I understand that other CMSs have places where you might edit code in the CMS, and I also understand there is a convenience factor in many cases. But the main reason why I want to support snippets is actually to encourage sharing of code snippets. It's feasible that we can have a library of snippets that people can just paste in, and this is accessible to anyone. This is the area where I think the snippets may be worth the compromise of their downside. But I will do as you suggested and document why people might want to avoid using snippets for custom site-specific code, or plugging things into live sites. Thanks, Ryan -
Sure--let me know how it works for you and if you have any thoughts on expanding it further. Thanks, Ryan
-
$pages->get from a Custom Process module
ryan replied to peterb's topic in Module/Plugin Development
Hi Peter, I'm glad to see you extended a Process module and used it in the Admin. I think you are the first to do this. To iterate the fields in a template, you would do: <?php foreach($template->fields as $field) { echo "<li>{$field->name} is a field of type {$field->type}</li>"; } In the top of your .module file, I recommend adding one or more lines indicating that you are the author and any related contact info (website, etc.). Likewise, in your getModuleInfo() function, I recommend changing it to: public static function getModuleInfo() { return array( 'title' => 'Export XML for Flash', 'version' => 100, 'summary' => 'A module to export XML for flash by PeterB', ); } There is still a lot of stuff left in your module from the one you adapted it from, so you can remove lots of unnecessary code, which I'll cover below. Remove your init() function, you don't need it or anything that's in it. You don't need the code that is in your execute() function. You can change your execute() function to be just: public function ___execute() { return "<p><a href='./export'>Export XML for Flash</a></p>"; } In your executeExport function: It's not safe to assume that the assets dir is "../assets/". Instead, you should set your filename like this: $myFile = $this->config->paths->assets . "website.xml"; In general purpose situations, it's probably not safe to find your homepage with a selector like $pages->get("title=Home"). That's because it's feasible that other pages could have that title. I would instead suggest using the homepage's path, like $pages->get("/"); There are also other instances where you are retrieving a page with it's title field. If that's something that you need to do, I would suggest instead using the page's path/url or ID, as those are the only two things guaranteed to be unique about any given page. For pages with the same parent, you can also assume that it's "name" will be unique among it's siblings. On this line (119): $subpage = $this->pages->get("title=$section->title"); $stories = $subpage->children; Is that necessary? On briefly looking at the code, it looks to me like this would achieve the same thing: (?) $stories = $section->children; In your code, you are referring to a field called "page_type". Since this is essentially what a template is, you may want to see if using a Template for a page type would suite your needs (it's possible it may not). At the end of your executeExport function, you have the following: $out = $this->showListFilters || $this->config->advanced ? $this->renderListFilters() : ''; $table = $this->modules->get("MarkupAdminDataTable"); $table->action(array('Export XML for Flash' => './export')); $table->message("Exported!"); return $out . $table->render(); I believe you can delete all of that and replace it with: $this->message("Exported!"); return $this->execute(); Also, you can delete everything after your executeExport() function, as they are functions specific to the Fields module, and ConfigurableModule interface, and they aren't used here. Lastly, go back to the beginning of the file and change your class definition to be just: class ProcessExportFlashXml extends Process { You want to make sure you remove the "implements ConfigurableModule" since it will throw an error if you don't (since I told you to remove everything below your executeExport function. -
$pages->get from a Custom Process module
ryan replied to peterb's topic in Module/Plugin Development
The reason it's not working is because a page's output formatting is usually only turned on for template use, and off elsewhere. Technically, all image fields can contain multiple images, but ProcessWire automatically reduces them for templates when you want them to be just one (likewise for Page references). It doesn't do this for the rest of the API just so that the same bits of code can always be used regardless of the image settings. Whereas in your templates, it lets you choose. Here's a couple of options to make it work in your instance: $url = $section->imagefield->first()->url; Or $section->setOutputFormatting(true); $url = $section->imagefield->url; $section->setOutputFormatting(false); -
You can definitely do everything that you can in those other CMSs. But another thing to note is that both Drupal and Wordpress are primarily bucket-based CMSs, whereas ProcessWire is a page hierarchy-based CMS (as are MODx and SilverStripe, as far as I know). In a bucket-based CMS, you have no hierarchy other than an individual bucket. So custom taxonomies/categories/tags become the primary means by which you establish hierarchy (beyond a content type). Whereas in a page-hierarchy based CMS, you already have a hierarchy present which directly relates to URL structure. So additional categorization is less often used than it would be on a bucket-based CMS. I'm not suggesting that one approach is necessarily better than the other for most sites, except that I prefer a page hierarchy-based approach that can be used like a bucket when the need calls for it (which is ProcessWire's approach). I also feel that the page hierarchy approach is demonstrate-ably better at the large scale. I have a feeling we have the same preferences in this area, based on the other CMSs I know you like working with.
-
Snippets / chunks / blocks / template inside templates
ryan replied to piranha's topic in Wishlist & Roadmap
Snippets will be supported with a module, and you'll be able to define whether you want it to process PHP or not. I'd rather not have a bunch of confusing terminology like chunks, nuggets, snippets and such, and rather just have one term for them all: snippets. I understand the desire for snippets, though admittedly feel it crosses the line away from best practices, splitting your markup into different places. Whereas include files are clean, simple, are kept in one place, and don't need to be eval'd when they contain PHP. I also think it's a bad practice for people to be editing any sort of code in the CMS itself. The CMS is not the right environment for it (your markup and/or code editor is), nor is a live site the place to be messing with the code (this should be a dev/staging/offline task). But the intention with ProcessWire is to adapt to a developer's needs rather than enforce my opinions on best practices, so a snippets capability is something you can count on in the future. Thanks, Ryan -
Piranha, I'm not suggesting that you should create lots and lots of templates. What I am suggesting is that your templates are PHP files, not static files, so you are not bound to the limits of static files. On my sites, I typically have only one markup template, and use the other templates as flow control in preparing whatever is needed for the main template. But you should use templates in whatever way works best for you. The need you mentioned with using a tag within the content of an existing field is one I can relate to. The need does come up occasionally. Though I don't like my clients having to use tags, so I usually design in a way that maintains separation between their content and that which is generated at render time. But that may not be right for you, so I'm going to take Adam's suggestion and turn it into a module. This took all of 10 minutes to create, but it should give you a good starting point to build from. Though it is fully functional as-is. Place the attached module file in /site/modules/TagscriptSimple.module. Then go to Admin > Modules and click the "check for new modules" button at the bottom. Then locate the TagscriptSimple module, and click "install" on that screen. Now in any of your page fields (or templates) you can type a {{tag}} which can either be a page property or a function name. For example {{title}} would echo the current page's title. Or {{myfunction}} would call a function named tagscript_myfunction, and it would pass it the current page. It would then replace the {{myfunction}} tag with whatever output was returned by the function. I included a couple of examples in the module code if you want to try them, so try {{hello}} as well as {{children}} to see the examples run. Here is the module code. I've also attached it in a ZIP file ready do download, so that you don't need to copy/paste. This is fairly basic. Anyone please feel free to take this further, and please post the update. An example of how you want to take it further would be to translate some tags to config URLs, or to include the ability for tags to pass arguments. Though if nobody takes this up, I'll do it here. <?php /** * Simple tagscript parser to serve as an example or starting point. * * Looks for tags surrounded by double curly brackets, like {{example}}. * When it finds one, it first checks if there is a funcing matching the * name: tagscript_example(). If it finds a matching function, then it * calls it, passing it the current $page object (in case it needs it). * The function should return whatever should replace the tag. * * If the matching tag doesn't resolve to a function, then it next checks * if the tag lines up with a field from the current page. If so, the * tag is replaced with the field's value from the page. * */ class TagscriptSimple extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Tagscript Simple', 'summary' => 'Translates {{tags}} to PHP function calls.', 'version' => 100, 'permanent' => false, 'autoload' => true, 'singular' => true, ); } public function init() { $this->addHookAfter('Page::render', $this, 'render'); } public function render(HookEvent $event) { $page = $event->object; $out = $event->return; // don't process tags in the admin if($page->template == 'admin') return; // quickly determine if there are no parsable tags here if(strpos($out, '{{') === false) return; // match all tags enclosed by double brackets, like {{tag}} if(!preg_match_all('/\{\{([_a-z0-9]+)\}\}/i', $out, $matches)) return; // iterate through all found tags foreach($matches[1] as $key => $value) { // first determine if there is a function with the same name as the tag // except preceded by "tagscript_", i.e. "tagscript_functionName" $functionName = "tagscript_$value"; // if the function exists, then call it, passing it the $page object if(function_exists($functionName)) { $result = call_user_func_array($functionName, array($page)); if($result !== false) $out = str_replace($matches[0][$key], $result, $out); // if function doesn't exist, check if it's a page property } else if(($result = $page->get($value)) !== null) { $out = str_replace($matches[0][$key], $result, $out); // if none of the above, then leave it alone } else { // do nothing, or expand from here... } } $event->return = $out; } } Here are a couple of example functions I also put in to test. These are just regular functions (not class functions). <?php /** * Function to test the tagscript parser * */ function tagscript_hello($page) { return "<p>Hello World. The current page path is {$page->path}</p>"; } /** * Render a list of the page's children * */ function tagscript_children($page) { if(!$page->numChildren) return ''; $out = "<ul class='children'>"; foreach($page->children() as $child) { $out .= "<li><a href='{$child->url}'>{$child->title}</a></li>"; } $out .= "</ul>"; return $out; } TagscriptSimple-module.zip
-
Here's how I setup 301 redirects in my .htaccess files. These redirect directives should go probably above ProcessWire's, but after the "RewriteEngine On" directive. Here's a 301 redirect from one directory to another (/old/ to /new/): RewriteRule ^old/?$ /new/ [R=permanent,L] Here's rewriting /old.html to /new/dir/: RewriteRule ^old.html$ /new/dir/ [R=permanent,L]