salles Posted December 5, 2014 Share Posted December 5, 2014 Hi guys I'm building a repository for inspirational images found through the web, so I have something like this: Images - Image 1 - Image 2 - Image 3 ..... Sources - Source 1 - Source 2 - Source 3 ... Each image template has the following fields: - URL fieldtype for the Source Link (for example, http://abduzeedo.com/daily-inspiration-1940) - Page fieldtype for the Source Site (where it connects to the Sources page all the image sources) So I was wondering if it's possible to automatically get the base domain from the Source Link and save to the Sources page. For example, the Source Link is http://abduzeedo.com/daily-inspiration-1940, so it automatically saves "abduzeedo.com" to the Source Site fieldtype, consequently to the Sources pages. Is it possible to do something like this? Link to comment Share on other sites More sharing options...
horst Posted December 5, 2014 Share Posted December 5, 2014 To get the part of the url you can use parse-url 1 Link to comment Share on other sites More sharing options...
salles Posted December 5, 2014 Author Share Posted December 5, 2014 But is it possible to automatically save it to pages? Link to comment Share on other sites More sharing options...
kongondo Posted December 5, 2014 Share Posted December 5, 2014 But is it possible to automatically save it to pages? Are you looking for an affirmation or a code example? Link to comment Share on other sites More sharing options...
Philipp Posted December 5, 2014 Share Posted December 5, 2014 Why store the domain twice, if you already have the full source URL? Just ouput the part from the source URL field you want to display like horst mentioned: <? echo parse_url($page->source_url,PHP_URL_HOST);?> If you want to store it additionally, look at the HelloWorld.module demo and try to hook after each page save and write the field. 3 Link to comment Share on other sites More sharing options...
salles Posted December 5, 2014 Author Share Posted December 5, 2014 I even tried to write a module, but i just can't get my head around it programming - it's ok the php template part, but when it comes to writing modules i feel stupid would anybody be willing to make this code for me? i'll pay... Link to comment Share on other sites More sharing options...
Philipp Posted December 5, 2014 Share Posted December 5, 2014 Not tested and quickly put together here based on the HelloWorld.module demo. This should give you an starting point. Hook before the page saves (I think this is possible?), then write the other field based on the source_url field. <?php /** * ProcessWire 'Hello world' demonstration module * * Demonstrates the Module interface and how to add hooks. * * See README file for further links regarding module development. * * ProcessWire 2.x * Copyright (C) 2014 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://processwire.com * */ class Helloworld extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( // The module'ss title, typically a little more descriptive than the class name 'title' => Rewrite field after save', // version number 'version' => 1, // summary is brief description of what this module is 'summary' => 'An example module used for demonstration purposes. See the /site/modules/Helloworld.module file for details.', // Optional URL to more information about the module 'href' => 'http://processwire.com', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. 'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). 'autoload' => true, // Optional font-awesome icon name, minus the 'fa-' part 'icon' => 'smile-o', ); } /** * Initialize the module * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. * */ public function init() { // add a hook before the $pages->save, to issue a notice every time a page is saved $this->pages->addHookBefore('save', $this, 'saveShortUrl'); } /** * Save as another field. * */ public function saveShortUrl($event) { $page = $event->arguments[0]; //#todo Rename to your field names. $page->domain = parse_url($page->source_url,PHP_URL_HOST); //#todo Maybe some more error handling. $this->message("Save the domain {$page->domain}."); } } But maybe the experts on this topic hand help you with any further questions Link to comment Share on other sites More sharing options...
salles Posted December 6, 2014 Author Share Posted December 6, 2014 @Philip The message "save the domain..." appears, but it doesn't save anywhere... Here's what I'm trying: $pages->get("sources")->find("domain") = parse_url($page->link_to_img, PHP_URL_HOST); I'm trying to get the page "Sources" and their children field "domain", so each page under "Sources" is a saved domain. But it doesn't work either... Link to comment Share on other sites More sharing options...
adrian Posted December 6, 2014 Share Posted December 6, 2014 I think Phillip inadvertantly forgot the actual save part Try this: public function saveShortUrl($event) { $page = $event->arguments[0]; //#todo Rename to your field names. $page->domain = parse_url($page->source_url,PHP_URL_HOST); //#todo Maybe some more error handling. $page->of(false); $page->save("domain"); $this->message("Save the domain {$page->domain}."); } As Phillip mentions - you need to have a field called "domain", or rename both instances of "domain" in the code above. Hope that helps. 1 Link to comment Share on other sites More sharing options...
salles Posted December 6, 2014 Author Share Posted December 6, 2014 @adrian i'm getting this error when i try to install the module: Error: Call to undefined method stdClass::of() (line 29 of /Users/SF/Sites/pw/site/modules/saveShortUrl.module) line 29 is this: $page->of(false); Link to comment Share on other sites More sharing options...
adrian Posted December 6, 2014 Share Posted December 6, 2014 Can you show us the full code for the module that you are using now. The code chunk I posted works if used with the rest of the module that Phillip posted. i am not completely sure it does what you want, but it definitely does what it is supposed to do Link to comment Share on other sites More sharing options...
Soma Posted December 6, 2014 Share Posted December 6, 2014 ShouldnT I be $page = $event-> object Link to comment Share on other sites More sharing options...
adrian Posted December 6, 2014 Share Posted December 6, 2014 ShouldnT I be $page = $event-> object Actually, if I use $event->object, I get "Method Pages::of does not exist or is not callable in this context" But it works fine for me with: $event->arguments[0] Link to comment Share on other sites More sharing options...
salles Posted December 6, 2014 Author Share Posted December 6, 2014 i erased everything to try again and i'm still getting that error when i try to install the module here's the full code of saveShortUrl.module that i'm using: <?php class saveShortUrl extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Rewrite field after save', 'version' => 1, 'summary' => 'An example module used for demonstration purposes. See the /site/modules/Helloworld.module file for details.', 'href' => 'http://www.processwire.com', 'singular' => true, 'autoload' => true, 'icon' => 'smile-o', ); } public function init() { // add a hook before the $pages->save, to issue a notice every time a page is saved $this->pages->addHookBefore('save', $this, 'saveShortUrl'); } /** * Save as another field. **/ public function saveShortUrl($event) { $page = $event->arguments[0]; //#todo Rename to your field names. $page->domain = parse_url($page->source_url,PHP_URL_HOST); //#todo Maybe some more error handling. $page->of(false); $page->save("domain"); $this->message("Save the domain {$page->domain}."); } } i'm using a field "domain" and a field "source_url" Link to comment Share on other sites More sharing options...
Soma Posted December 7, 2014 Share Posted December 7, 2014 Take this <?php class SaveShortUrl extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Rewrite field after save', 'version' => 1, 'summary' => 'An example module used for demonstration purposes. See the /site/modules/Helloworld.module file for details.', 'href' => 'http://www.processwire.com', 'singular' => true, 'autoload' => 'template=admin', 'icon' => 'smile-o', ); } public function init() { // add a hook before the $pages->save, to issue a notice every time a page is saved $this->pages->addHookBefore('save', $this, 'hookPageSave'); } /** * Save as another field. **/ public function hookPageSave(HookEvent $event) { $page = $event->arguments[0]; if($page->template != "yourtemplate") return; //#todo Rename to your field names. if(!$page->source_url) return; $page->domain = parse_url($page->source_url,PHP_URL_HOST); //#todo Maybe some more error handling. $page->of(false); $page->save("domain"); $this->message("Save the domain {$page->domain}."); } } You should name a module first letter uppercase. SaveShortUrl.module and name the class the same "SaveShortUrl" Next you should avoid using a method name same as the class name, that leads to getting called when initialized. In this case the ($event) is not set etc. You only want to execute the method when the hook is executed. Further improvements to the module could be to make autoload a selector to only get loaded in backend: "autoload" => "template=admin". Check for the template or if the field exists or if there's a string could also help. 2 Link to comment Share on other sites More sharing options...
Soma Posted December 7, 2014 Share Posted December 7, 2014 Had to correct some code after posting, sorry. Link to comment Share on other sites More sharing options...
salles Posted December 7, 2014 Author Share Posted December 7, 2014 @Soma hi Soma, I made the changes you suggested, but I'm getting this error now: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'SaveShortUrl' for key 'class' Link to comment Share on other sites More sharing options...
Soma Posted December 7, 2014 Share Posted December 7, 2014 Version two would then be <?php class SaveShortUrl extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Rewrite field after save', 'version' => 2, 'summary' => 'An example module used for demonstration purposes. See the /site/modules/Helloworld.module file for details.', 'href' => 'http://www.processwire.com', 'singular' => true, 'autoload' => 'template=admin', 'icon' => 'smile-o', ); } public function init() { /** * Hook called just before a page is saved * * May be preferable to a before(save) hook because you know for sure a save will * be executed immediately after this is called. Whereas you don't necessarily know * that when before(save) is called, as an error may prevent it. */ $this->pages->addHookAfter('saveReady', $this, 'hookPageSave'); } /** * Save domain info to another field * No need to call page->save() when changing a value * as it will get saved just after this call. * * Make sure there's something in source_url and it has actually changed * with $page->isChanged(what) */ public function hookPageSave(HookEvent $event) { $page = $event->arguments("page"); if($page->template != "basic-page") return; if(!$page->source_url) return; if(!$page->isChanged("source_url")) return; $page->domain = parse_url($page->source_url, PHP_URL_HOST); if($page->domain) $this->message("Saved the domain: {$page->domain}."); } } @Soma hi Soma, I made the changes you suggested, but I'm getting this error now: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'SaveShortUrl' for key 'class' now you have already a module in the "modules" table in your DB, go to phpmyadmin and remove the entry for "saveShortUrl" Come back and refresh modules, and install the new one. 2 Link to comment Share on other sites More sharing options...
salles Posted December 7, 2014 Author Share Posted December 7, 2014 @Soma it works perfectly now Soma, thank you! I'm using a text field for the "domain", but could I use a page field? So domains can be saved as childrens of "Domains" page in the tree. -edit nevermind, it doesn't work. i'll stick with the text field and then make the search via the field. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now