Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/30/2017 in all areas

  1. Hello All ... I just added a new Site Profile Based on Spectre.css ... A lightweight profile that can be the basis for your blog . There are several pages like About Us, Blog, Contact Page, Categories, Authors ... He also uses the Font Awesome. CAN DOWNLOAD FROM THIS LINK: http://modules.processwire.com/modules/site-spectre/ https://github.com/rafaoski/site-spectre Live Example Some Screenshots: If you enable multilingual support, you will have a simple menu for switching between languages.
    8 points
  2. @dragan http://modules.processwire.com/modules/import-external-images/
    3 points
  3. @Robin S. Excellent solution! I think it is worth mentioning in the other thread that the solution does work (and cross-reference it with this GIF)...to help those who come across that thread. Ta.
    3 points
  4. Despite Soma helpfully telling us we are all wrong, the code I suggested in that thread works for me: So you set up a field in each PageTable template to hold some reference to the container page - in the example below I use an integer field for the page ID, but you could use a Page Reference field instead. You would set the field to hidden so users do not see or change it. But for demonstration purposes I have left the field visible and also show the value in the PageTable columns. Note that the value is only set when the PageTable field does the AJAX reload (when the modal closes), so the value is not available when adding a new page to the PageTable until the modal is closed. In /site/init.php $wire->addHookBefore('InputfieldPageTableAjax::checkAjax', function($event) { $field_name = $this->input->get('InputfieldPageTableField'); // Just for this PageTable field if($field_name !== 'test_pagetable') return; $page_id = (int) $this->input->get('id'); $item_id = (int) $this->input->get('InputfieldPageTableAdd'); if($page_id) $page = $this->pages->get($page_id); // $page is the container page if($item_id) $item = $this->pages->get($item_id); // $item is the PageTable item // Set integer field to $page->id $item->setAndSave('container_page_id', $page->id); });
    3 points
  5. @wbmnfktr I removed the security related link, which was outdated anyways, as it was for the 2.x legacy version of ProcessWire. Right now, for PW3 there are no documented security flaws. The article is now translated into English and available here: https://jensmartsch.de/blog/why-processwire-is-the-best-choice-for-your-website Additions and comments are welcome. I also updated the first post, with links to both versions.
    3 points
  6. thank you all, we decided to go for an automated page creation through a json import script. a dear friend helped me with this. perhaps some one in the future stumbles across this topic and finds this helpful, below the import script <?php $TEMPLATE_COUNTRY = "country"; $TEMPLATE_REGION = "region"; $TEMPLATE_SUPPLIER = "supplier"; $TEMPLATE_WINE = "wine"; $rootid = wire('pages')->get('title=wines')->id; // All Wines: $file = "./lijst.json"; $raw = file_get_contents($file); // clean: replaces newlines in strings with \n and some other $raw2 = preg_replace('/\n(\w*)([^ \t\]\[{}"])/', '\\n$1$2', $raw); $data = json_decode($raw2, TRUE); $wines = $data['data']; // trash country pages + children before import $pages = wire('pages')->find('template=' . $TEMPLATE_COUNTRY); foreach($pages as $p) { $p->trash(); } foreach($wines as $wine) { // do the country pages $country = $wine['country']; // create new page is not exists $country_pages = wire('pages')->find('title="' . $country . '"'); if ($country_pages->count == 0) { $country_page = new Page(); $country_page->template = $TEMPLATE_COUNTRY; $country_page->title = $country; $country_page->parent = $rootid; $country_page->country_text = $wine["country_text"]; $country_page->save(); } // update exsiting else { $country_page = $country_pages[0]; } // do region pages $region = $wine['region']; if (!$region) { $region = "Other"; } $region_pages = wire('pages')->find('title="' . $region . '"'); if ($region_pages->count == 0) { $region_page = new Page(); $region_page->template = $TEMPLATE_REGION; $region_page->parent = $country_page->id; $region_page->title = $region; $region_page->region_text = $wine['region_text']; $region_page->save(); } else { $region_page = $region_pages[0]; } // do supplier pages $supplier = $wine['supplier']; // outlyer: wine without region ... should fix in source json if (!$supplier) { $supplier = "Other"; } $supplier_pages = wire('pages')->find('title="' . $supplier.'", parent='.$region_page->id); if ($supplier_pages->count == 0) { $supplier_page = new Page(); $supplier_page->template = $TEMPLATE_SUPPLIER; $supplier_page->parent = $region_page->id; $supplier_page->title = $supplier; $supplier_page->supplier_text = $wine['supplier_description']; $supplier_page->save(); } else { $supplier_page = $supplier_pages[0]; } // do wine pages $wine_page = new Page(); $wine_page->template = $TEMPLATE_WINE; $wine_page->parent = $supplier_page->id; $wine_page->title = $wine['wine']; $wine_page->wine_text = $wine['wijnomschrijving']; // same wine ... multiple years $year = $wine['year']; if (!$year) { $year = ''; } $wine_page->year = $year; // add 00s after comma if not there $price = preg_replace('/\.[0-9]$/', '${0}0', ''.$wine['price']); $price = preg_replace('/^[0-9]+$/', '${0}.00', ''.$price); $wine_page->prijs = $price; $wine_page->save(); } ?> curious to hear if any one wants to improve/comment on this thanks again!
    2 points
  7. the only userfriendly take that i know is going with the repeater matrix or pagetable route, in one project i drilled it with PageTableExtended with rendered Output on Admin Side and different "blocks" of content that a editor could add such as galleries, maps, text with image right or left....and full control over markup on frontend. WYSIWYG with full power is always a mess...on every system. If i've time to play i would try out a combination of repeater matrix for the storage in admin and some kind of "add block" layer on frontend with frontend edit for the single blocks...so user works complete in frontend....this would be one step more userfriendly since everyone see instant like it is rendered in frontend...but that is just in my mind for now
    2 points
  8. Hey @bernhard thanks for testing it ! I changed all the __() to _() before releasing the module, I don't know why, so I have no answer here lol I think it was a bit late for my brain. I will fix it in the next version. Yes I can, I was thinking in the first time to check if the ProcessModule is installed and if yes, it show the link to the manager, if not then no link appear. Why ? because the ProcessModule is optional, you can configure Duplicator, the cron job and everything will run without using the manager. But its just an idea. I will test it under Windows, look like something weird is happening while adding the information to the config.php. Thanks again for reporting theses issues !
    2 points
  9. i was curious, this worked for me: https://jsfiddle.net/3L0cdjsj/5/ -- removed -- You can change the description (item_name) and the price (amount) and you can use a button in your own style that fits to your website.
    2 points
  10. Hi guys! I've been a bit away from the forums lately but I didn't forget you all (well, I'm not writing much, but visit all the time) Here is our latest site http://www.plateau.studio The design is by Plateau themselves. Some of you will probably recognize "The Weekender" magazine from their portfolio, since we also did their site some time ago https://www.the-weekender.com
    2 points
  11. Some nice updates this morning for the Console and the Snippets Runner panels. 1) The code injection feature (the one that lets you run hooks etc at init, ready, and finished) now has better error handling. It will no longer inject code if it detects any type of error (previously it wasn't properly detecting 500 errors). 2) The Console panel now makes use of orange and red icon colors. The orange simply indicates that you are currently injecting code, and the red indicates that there is an error in your code and as such, nothing is being injected. 3) The Console panel now restores the last error to the results section on page load so if you missed the error when you clicked "Run" to register the code, you will see it again as a reminder of what needs fixing. 4) 500 errors in the Console and Snippet Runner panels now show the full error message - previously this had to be tracked down in the browser dev console's Network tab. Hopefully these changes will be nice improvements to debugging code in the Console and Snippet Runner panels. Let me know if you notice any problems. Cheers! PS I have been using the Console code injection feature for all my hook testing lately and really enjoying it.
    2 points
  12. There you can download the module : https://github.com/flydev-fr/Duplicator The documentation is incomplete, you have for now to explore the settings on your own. The install instructions are written but the SDKs are not uploaded yet, which mean that AmazonS3, Dropbox and GoogleDrive are only available by installing them through composer. I will upload them tomorrow but they are not recently tested. Anyway, there is no requirements to run Duplicator as is. Just install Duplicator and Duplicator - Packages Manager then go to Setup > Duplicator and build your package by clicking the button. If everything run smooth, you will see the package listed and you will be able to download it directly and also the installer. To restore a website, just upload the package and the installer then go to yourwebsite.com/installer.php then follow the instructions. PLEASE, do not forget - after the end of the process - to delete the installer.php file and your package (this will be fixed in the v0.0.45). It should work with default theme and the UIkit theme. A dedicated thread will be created in the modules forum soon. Do not hesitate to share here your results by providing your hosting type / provider / config, etc.
    2 points
  13. Might sound a little insignificant to mention, but I have found myself using the GOTO Page ID feature a lot but it was annoying me that there was no way to open the View/Edit links in a new tabs. Well, now you can - just use your standard "new tab" shortcut: middle-click, right-click > new tab, CTRL+left-click, 3-finger click, etc - really handy!
    1 point
  14. Bernhard!!! I think that'll work. I modified the form markup you fiddled to make the amount field a text field rather than hidden and was able to complete the transaction with a custom amount I entered. I still have to test it some more but wow, thank you for the assistance.
    1 point
  15. Sorry, that's my fault, I've mixed the string vs numeric versioning and that's why the chaos (adrian reminded me). Next time I'll double check
    1 point
  16. Welcome to the forums. As first questions go, that's a doozy. And I'm not even going to try for a definitive answer, but let's just think out loud a bit. I like the sound of this. Once you've got your initial structure could you maybe query individual products on page load? (You probably wouldn't want to do this on every page load, just after a certain time since the last call, kind of like a cache.) Then return the info or an 'out of stock' or 'discontinued' message. That saves deleting pages and preserves any link juice that individual products might have garnered over time. You could also set up some kind of alternative product suggestion for those pages ('We're sorry, but X is no longer available, what about Y?') - good for internal linking and keeping visitors on-site, then after a period (6 months or a year maybe) turning that suggestion into a 301. Is it possible to ask the host system just for new or updated records? Either way, a cron or lazy cron is probably going to be involved. The good news is that iterating over all 600 or so records isn't going to take forever, even if that is the only way forward. Break it down into bite sized chunks. Solve one small aspect at a time. Not a complete answer, I know, but I'm sure others will chime in.
    1 point
  17. Great chance to grab a Pluralsight subscription at 33% off at USD 199/yr The caveat being it is only for the first year of an annual subscription. Offer ends 1st of Dec, midnight MST. https://learn.pluralsight.com/offers/2017/black-friday
    1 point
  18. Ah, I understand! Ok then a message would be nice to keep the first steps for everybody as easy as possible. Thanks!
    1 point
  19. hi flydev thanks for releasing this i just tried it and i got multiple errors "call to undefined function _(...". i changed all occurences from _( to __( and it worked. what is this single underscore function that you are using for translations? same for the process module. also i get an "unrecognized path" for http://duplicator.dev/processwire/setup/Duplicator/?action=packages can you set the process module to be installed automatically by the main module please? the backup worked like a charm. the installer seems to be quite similar to my kickstart project. i think there is great potential to combine both tools! unfortunately i got an error on the last step: the problem seems to be the config.php /** * Installer: Database Configuration * */ $config->dbHost = 'localhost'; $config->dbName = 'localhost'; $config->dbUser = 'localhost'; $config->dbPass = 'localhost'; $config->dbPort = 'localhost'; /** * Installer: User Authentication Salt * * Must be retained if you migrate your site from one server to another * */ $config->userAuthSalt = 'localhost'; /** * Installer: File Permission Configuration * */ $config->chmodDir = 'localhost'; // permission for directories created by ProcessWire $config->chmodFile = 'localhost'; // permission for files created by ProcessWire /** * Installer: Time zone setting * */ $config->timezone = 'localhost'; /** * Installer: Admin theme * */ $config->defaultAdminTheme = 'localhost'; /** * Installer: Unix timestamp of date/time installed * * This is used to detect which when certain behaviors must be backwards compatible. * Please leave this value as-is. * */ $config->installed = 1512033277; /** * Installer: HTTP Hosts Whitelist * */ $config->httpHosts = array('localhost', 'localhost'); as you can see im on windows + laragon. i used the latest dev version of pw
    1 point
  20. I have found the problem: when adding the options in my textarea i need to include the id so instead of: cat1 cat2 cat3 I need to fill in 1=cat1 2=cat2 3=cat3 my final code: $this->addHookAfter('Pages::saved', function($event) { $page = $event->arguments[0]; //set the page //get the subcategories from the parent textarea, split on newline $subcats = preg_split('/[\n\r]+/', $page->subcats); //implode the items with a newline $subcats = implode("\n",$subcats); switch ($page->template) { case 'winkels-overzicht': //set the options $field = $this->fields->winkel_categorie; $this->modules->get('FieldtypeOptions')->manager->setOptionsString($field, $subcats, true); break; case 'sport-verenigingen-overzicht': //set the options $field = $this->fields->sport_categorie; $this->modules->get('FieldtypeOptions')->manager->setOptionsString($field, $subcats, true); break; case 'cultuur-overzicht': //set the options $field = $this->fields->cultuur_categorie; $this->modules->get('FieldtypeOptions')->manager->setOptionsString($field, $subcats, true); break; case 'vrijetijd-overzicht': //set the options $field = $this->fields->vrije_tijd_categorie; $this->modules->get('FieldtypeOptions')->manager->setOptionsString($field, $subcats, true); break; case 'horeca-overzicht': //set the options $field = $this->fields->horeca_categorie; $this->modules->get('FieldtypeOptions')->manager->setOptionsString($field, $subcats, true); break; default: break; } });
    1 point
  21. I'm not sure what was the point exactly. It works, but I need the id the moment I created the page table page not after saving it.
    1 point
  22. this is amazing, wish i saw this about 2 hrs ago (before i wasted a bunch of time trying it another way...)
    1 point
  23. Thanks once more! Will try it out tomorrow. I see, Christmas is coming early this year Can you pls explain why this line is necessary? if($template_field->type == 'hidden') {
    1 point
  24. It just so happens that there is... Templates: Child Pages You could use this in conjunction with the hook below, which will use the template context for title label, description and notes if the number of allowed templates has been restricted to one: $wire->addHookAfter('ProcessPageAdd::buildForm', function(HookEvent $event) { $form = $event->return; $template_field = $form->getChildByName('template'); if($template_field->type == 'hidden') { // Only one template is allowed for this new page // Get the template $template = $this->templates->get($template_field->value); // Get the title field in the context of this template $title = $template->fieldgroup->getFieldContext('title'); if($title) { // Set the properties of the 'title' inputfield $title_field = $form->getChildByName('title'); $title_field->label = $title->label; $title_field->description = $title->description; $title_field->notes = $title->notes; } } $event->return = $form; });
    1 point
  25. Another option: set $config->debug = true in /site/config.php (which is a good idea in general while developing a site) and then hover the inputfield collapse/expand icon in Page Edit.
    1 point
  26. Will this module work in a repeater? My use case is that the client needs to make a selection of a page, and then if that page has any children, it will show those as selectable. But they may need to do this multiple times on one page, hence the need for repeater support. I tried using the built in dependent select, e.g. parent=page.page_select_field, but this doesn't seem to work in a repeater (still references the edited page i think)...
    1 point
  27. i do have a client with a pretty big site where i do the cycle through the pages and set the owning page on those page table items; but now i have to add a cron job to set them because the client keeps forgetting to save the owning page and then even though those page table items are connected to the owning page by their existence in the page table field, they are still 'orphans' in the sense that the front end code we use needs to be able to identify any of those page table items' owning page without having to do a lookup; part of the reason is that this site was built before Page Table was invented; otherwise i think this method is the most reliable and easiest, here is some example code: if($page->template == 'class') { $sessionsUnset = $page->session_table->find("class="); foreach($sessionsUnset as $su) { $su->class = $page; $su->setOutputFormatting(false); $su->save(); $this->message("This class ({$page->title}) added to session {$su->id}"); } }
    1 point
  28. Just some more thoughts on this topic I just asked myself Why would someone use Drupal or Typo3 and therefore read what they write on their sites. https://www.drupal.com/product/web-content-management https://www.drupal.com/product/commerce https://typo3.com/about-typo3/why-typo3-cms/ The shocking truth is that they don't say anything new at all. Some arguments are valid, some are BUZZword Bingo but almost all of them match perfectly well with ProcessWire, too. If we wanted to create a huge list of arguments for ProcessWire we can find a lot of material out there in the interwebs. Can ProcessWire compete with Drupal or Typo3? I think we all know the answer. Next step Who uses Drupal or Typo3. http://www.typo3-websites.eu/en/typo3-cms/typo3-references/commercial-enterprises/ https://www.drupal.com/showcases This is way more interesting to look at. Big companies, big budgets and big agencies. Absolutely well designed sites well presented. Drupal plays the showcase-game very well. Every site gets a lot of attention. Not only a screenshot, a link to the website, a link to the creator and a few links to modules. Everything is a case study. Browsing the list of sites is a really nice experience and makes me want to try Drupal and built awesome sites. Could this be done with ProcessWire sites as well? Absolutely. Should we invest more time in presenting sites and projects? You guess it.
    1 point
  29. Had to play around with it and it works like a charm. Thank you @Kiwi Chris for sharing this. This will come in handy for smaller sites or prototypes. What I really like is that saving pages from the submitted form doesn't need an extra step as it does in FormBuilder. The created template is already the form and the template for the pages.
    1 point
  30. I'm running a few sites on IIS and never had problems, although I don't use ProCache (would you mind sharing web.config in regards to ProCache)? I also develop on IIS and everything works. Did you consult IIS/PHP log files? Event viewer?
    1 point
  31. I have a site in production with this Vue boilerplate. Indeed, I had problems with SEO and google took a long time to index all pages, I used https://prerender.io/ for indexing nested routes otherwise google wouldn't have been able to do so. It really depends on the type of app you're building, but if you can install node in the server you could use nuxt.js and in this way every route will be easily indexed. However you'll have to either build your REST API with node or connect to it with PW. If it is not managed by a client you can just use nuxt.js as is.
    1 point
  32. Hi, if I'm not mistaking, you can check if a specific option is selected using the has() method. So in your case one of these options should work: if ($page->portfolio_type->has(1)) { ... } //assuming the option is defined as: "1=A Project" if ($page->portfolio_type->has("title='A Project'")) { ... } Hope this helps. Edit: Background should be that the option field returns a WireArray. Which has the has() method for checking its content.
    1 point
  33. to @Ryan and dev team. It has happened that I've started development of notification system for users and found that there is already SystemNotifications module and related classes in core. Before development of own bicycle I've decided to check if it is required) and/or use a chance to add few wishes at moment when this module is under development. Please could you share thoughts/plans on the following: 1. currently flags in Notification are protected static. It limits possibilities to extend class by adding custom flags and handlers for these flags in FieldtypeNotifications. For example, notification flags for SMS or messengers, like Telegram. They can (and probably should) be handled in FieldtypeNotifications in the same manner as emails. At my site I use both SMS and Telegram notifications. Also, I think preferred notification methods should be set by (or for) user. 2. emails (as well as other "contacts" like cellphone number for SMS, etc) could be taken from different user fields, depending on some condition. In my system for example, sales managers roles need to get internal emails to corporate emails while being users, they get emails from system email field. E.g. "contact fields" should be customizable and/or hookable. 3. currently notifications are removed as soon as user closes them. There could be notifications that require action(s) (e.g. changes at some page); while these actions are not performed, notification should remain. E.g. it is some form of "todo" notification controlled by the system. Also there could be actions which can not be controlled by system, e.g. user should either confirm "done" or "cancel" or "postpone" them manually. Do you consider such "to-do" notifications as something that should be developed separately OR you think that they may be realized in the scope of SystemNotifications? 4. currently at UI level notifications are injected through predefined core js/css and predefined admin DOM structure. This limits possibilities to make notifications UI different. For example, I'd prefer to give my users "Facebook style" icon & attached notifications menu. Is it possible to leave hooks and/or module config params that opens a space for js/css replacement/adjustment and possibly more admin DOM extras (like adding menu items)? Thank you!
    1 point
  34. You're very close actually . This is how it works: if($modules->isInstalled("MarkupBox")) { // do something }
    1 point
×
×
  • Create New...