Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/01/2017 in all areas

  1. This week we have a guest post from Bernhard Baumrock that is a nice introduction to creating Process modules in ProcessWire. Bernhard covers a lot of useful material here and we hope you enjoy it. Big thanks to him for his contribution this week. I've been traveling (Ryan) for the last two weeks, but arrived back in town last night, so next week we'll be back to our regular PW core updates and schedule. https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/
    14 points
  2. Just tried out the latest dev version and experienced the new admin area. Damn, this is a beautiful CMS. Can't wait to see how my clients react to this.
    7 points
  3. Tweak the backend with your client's brand colors, their logo and a nice favicon. BOOM... they will feel like home.
    6 points
  4. *Runs to update and try new version out* the day just got better
    4 points
  5. 4 points
  6. Just had this for breakfast! Brilliant work @bernhard ! Really shows the power of PW in a very pragmatic way.
    3 points
  7. Thanks @flydev ... Now the menu should work already well. I changed the .btn-group class to flex-wrap: nowrap in _custom.scss file. Generally, this is my first template on this framework and I still learn about it, but I hope it will be useful to the community.
    3 points
  8. you can use https://processwire.com/docs/tutorials/how-to-use-url-segments/ you will get page/a-z instead of page/?sort=az ..using this segments you can search, filter, sort the pages results and update too the "sort box" (select, radio buttons, tabs, any) by this value
    2 points
  9. Yes, I have, although as I mentioned I am not saying it's an awesome service, but it seems to be relatively commonly used in Canada and so I thought it might be helpful for @digitex I have also used PayPal, Sallie Mae, and Frontstream with PW. Lots of options out there
    2 points
  10. 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.
    2 points
  11. You came to some pretty solid conclusions in less than a week
    2 points
  12. How can we take care of that padding ? Is it hard to find in the css to tweak it personally ?
    2 points
  13. Generally agree, we just need less padding: https://processwire.com/talk/topic/17786-pw-3084-–-core-updates-installer/?do=findComment&comment=156119 Maybe by being able to set it in the config? That would be great.
    2 points
  14. I pushed a small update this night : Fixed changed all _() call to __() for translation string the installer parse correctly the config.php file on windows machine small typo in ProcessDuplicator Added check if ProcessDuplicator module is installed, if yes, then display the link in the local folder overview to the manager I tested Duplicator on a Windows machine with PHP-5.6 and PHP-7.0, I could build a package and cloned the site without issue too.
    2 points
  15. @Macrura do you think it would be possible to update your module to also import images that were pasted from the clipboard? There is a ckeditor plugin that handles pasted image already. Maybe that could be a great addition!
    2 points
  16. After this tutorial you'll have learned how to: Build a Process module Make an AJAX request to backend Serve JSON as response Let's say you want to display the latest orders in a dashboard that you can access from admin panel. And you want it to refresh its content with a button click. Most straightforward and proper way (that I know of) is to create a Process module, as they're built for this purpose. First, create a directory under /site/modules/, call it ProcessDashboard, and create a file named ProcessDashboard.module under that directory. Following is about the least amount of code you need to create a Process module. <?php namespace ProcessWire; class ProcessDashboard extends Process { public static function getModuleInfo() { return [ 'title' => 'Orders Dashboard', 'summary' => 'Shows latest orders', 'version' => '0.0.1', 'author' => 'abdus', 'autoload' => true, // to automatically create process page 'page' => [ 'name' => 'order-dashboard', 'title' => 'Orders', 'template' => 'admin' ] ]; } public function ___execute() { return 'hello'; } } Once you refresh module cache from Modules > Refresh, you'll see your module. Install it. It will create an admin page under admin (/processwire/) and will show up as a new item in top menu, and when you click on it, it will show the markup we've built in execute() function. All right, now let's make it do something useful. Let's add create a data list to display latest orders. We'll change execute() function to render a data table. public function ___execute() { /* @var $table MarkupAdminDataTable */ $table = $this->modules->MarkupAdminDataTable; $table->setID($this->className . 'Table'); // "#ProcessDashboardTable" $table->headerRow([ 'Product', 'Date', 'Total' ]); // fill the table foreach ($this->getLatest(10) as $order) { $table->row([ $order['title'], $order['date'], $order['total'] ]); } // to refresh items $refreshButton = $this->modules->InputfieldSubmit; $refreshButton->name = 'refresh'; $refreshButton->id = $this->className . 'Refresh'; // "#ProcessDashboardRefresh" $refreshButton->value = 'Refresh'; // label of the button return $table->render() . $refreshButton->render(); } where getLatest() function finds and returns the latest orders (with only title, date and total fields) protected function getLatest($limit = 5, $start = 0) { // find last $limit orders, starting from $start $orders = $this->pages->find("template=order, sort=-created, limit=$limit, start=$start"); // Only return what's necessary return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total ]; }); } When you refresh the page, you should see a table like this Now we'll make that Refresh button work. When the button is clicked, it will make an AJAX request to ./latest endpoint, which will return a JSON of latest orders. We need some JS to make AJAX request and render new values. Create a JS file ./assets/dashboard.js inside the module directory. window.addEventListener('DOMContentLoaded', function () { let refresh = document.querySelector('#ProcessDashboardRefresh'); let table = document.querySelector('#ProcessDashboardTable'); refresh.addEventListener('click', function (e) { // https://developer.mozilla.org/en/docs/Web/API/Event/preventDefault e.preventDefault(); // Send a GET request to ./latest // http://api.jquery.com/jquery.getjson/ $.getJSON('./latest', { limit: 10 }, function (data) { // check if data is how we want it // if (data.length) {} etc // it's good to go, update the table updateTable(data); }); }); function renderRow(row) { return `<tr> <td>${row.title}</td> <td>${row.date}</td> <td>${row.total}</td> </tr>`; } function updateTable(rows) { table.tBodies[0].innerHTML = rows.map(renderRow).join(''); } }); And we'll add this to list of JS that runs on backend inside init() function public function init() { $scriptUrl = $this->urls->$this . 'assets/dashboard.js'; $this->config->scripts->add($scriptUrl); } Requests to ./latest will be handled by ___executeLatest() function inside the module, just creating the function is enough, PW will do the routing. Here you should notice how we're getting query parameters that are sent with the request. // handles ./latest endpoint public function ___executeLatest() { // get limit from request, if not provided, default to 10 $limit = $this->sanitizer->int($this->input->get->limit) ?? 10; return json_encode($this->getRandom($limit)); } Here getRandom() returns random orders to make it look like there's new orders coming in. protected function getRandom($limit = 5) { $orders = $this->pages->find("template=order, sort=random, limit=$limit"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total ]; }); } And we're done. When refresh button is clicked, the table is refreshed with new data. Here it is in action: 2017-04-29_19-01-40.mp4 (227KB MP4, 0m4sec) Here's the source code: https://gist.github.com/abdusco/2bb649cd2fc181734a132b0e660f64a2 [Enhancement] Converting page titles to edit links If we checkout the source of MarkupAdminDataTable module, we can see we actually have several options on how columns are built. /** * Add a row to the table * * @param array $a Array of columns that will each be a `<td>`, where each element may be one of the following: * - `string`: converts to `<td>string</td>` * - `array('label' => 'url')`: converts to `<td><a href='url'>label</a></td>` * - `array('label', 'class')`: converts to `<td class='class'>label</td>` * @param array $options Optionally specify any one of the following: * - separator (bool): specify true to show a stronger visual separator above the column * - class (string): specify one or more class names to apply to the `<tr>` * - attrs (array): array of attr => value for attributes to add to the `<tr>` * @return $this * */ public function row(array $a, array $options = array()) {} This means, we can convert a column to link or add CSS classes to it. // (ProcessDashboard.module, inside ___execute() method) // fill the table foreach ($this->getLatest(10) as $order) { $table->row([ $order['title'] => $order['editUrl'], // associative -> becomes link $order['date'], // simple -> becomes text [$order['total'], 'some-class'] // array -> class is added ]); } Now, we need to get page edit urls. By changing getLatest() and getRandom() methods to return edit links in addition to previous fields protected function getLatest($limit = 5, $start = 0) { // find last $limit orders, starting from $offset $orders = $this->pages->find("template=order, sort=-created, limit=$limit, start=$start"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total, 'editUrl' => $order->editUrl ]; }); } protected function getRandom($limit = 5) { $orders = $this->pages->find("template=order, sort=random, limit=$limit"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total, 'editUrl' => $order->editUrl ]; }); } and tweaking JS file to render first column as links function renderRow(row) { return `<tr> <td><a href="${row.editUrl}">${row.title}</a></td> <td>${row.date}</td> <td>${row.total}</td> </tr>`; } we get a much more practical dashboard.
    2 points
  17. Custom Inputfield Dependencies A module for ProcessWire CMS/CMF. Extends inputfield dependencies so that inputfield visibility or required status may be determined at runtime by selector or custom PHP code. Overview Custom Inputfield Dependencies adds several new settings options to the "Input" tab of "Edit Field". These are described below. Note that the visibility or required status of fields determined by the module is calculated once at the time Page Edit loads. If your dependency settings refer to fields in the page being edited then changes will not be recalculated until the page is saved and Page Edit reloaded. Usage Install the Custom Inputfield Dependencies module. Optional: for nice code highlighting of custom PHP install InputfieldAceExtended v1.2.0 or newer (currently available on the 'dev' branch of the GitHub repo). The custom inputfield dependencies are set on the "Input" tab of "Edit Field". Visibility Show only if page is matched by custom find Use InputfieldSelector to create a $pages->find() query. If the edited page is matched by the selector then the field is shown. Show only if page is matched by selector As above, but the selector string may be entered manually. Show only if custom PHP returns true Enter custom PHP/API code – if the statement returns boolean true then the field is shown. $page and $pages are available as local variables – other API variables may be accessed with $this, e.g. $this->config In most cases $page refers to the page being edited, but note that if the field is inside a repeater then $page will be the repeater page. As there could conceivably be cases where you want to use the repeater page in your custom PHP the module does not forcibly set $page to be the edited page. Instead, a helper function getEditedPage($page) is available if you want to get the edited page regardless of if the field in inside a repeater or not. $edited_page = $this->getEditedPage($page); Required The settings inputfields are the same as for Visibility above, but are used to determine if the field has 'required' status on the page being edited. https://github.com/Toutouwai/CustomInputfieldDependencies http://modules.processwire.com/modules/custom-inputfield-dependencies/
    1 point
  18. Hi, I have created a site profile that shows how to integrate ProcessWire 3.0 with Vue 2.0. See repository here. How this site profile works This ProcessWire site profile is loosely based on the REST API tutorial by @gebeer. Here are the most important steps to reproduce it: Admin settings Create an api template with default settings and just the title field assigned to it. Refer to @gebeer tutorial for further details Create a pages and nav templates with just the title field, for both template tick “Allow URL Segments” in the “URLs” tab (see attachment) Create a home template, this is going to be the single php file that will load your Vue SPA. Assign this template to the root of your website Any other template you create should have the “Alternate Template Filename” field in the “Files” tab set as home (see attachment), in this way if a user enter the website from any url that is not the root, ProcessWire will always redirect to the home template, Vue router will handle the url and call the right data through the REST API Under the root, create an api page and assign the api template to it (you can set “hidden” to this page so doesn't show up in the menu) Under the api page, create the pages nav and pages (see attachment), and assign the templates nav and pages to them. Now you have the www.sitename.com/api/pages and www.sitename.com/api/nav urls that you can use to fetch the JSON data PHP template setup In the templates folder, create home.php file and leave it empty, the HTML will be generated by webpack Now create pages.php and nav.php files. On these files is where we return the JSON data, based on the right url segment. Again, refer to @gebeer tutorial for further details on this matter. Note that I wrote a PageFields class that I use on these templates to fetch ProcessWire fields. The fields that are supported are text, textarea, repeater, img. Other fields may work but I haven't tested them. See the REST API setup for further details about how to use the PageFields class REST API setup You can decide what fields are included and what fields are excluded by passing a configuration array to the PageFields class. You can find here a list of the available configuration settings. See examples below. Show only selected core fields: $pageFields = new PageFields($p, [ 'fld_core_included' => ['url', 'httpUrl', 'template'] ]); Show no global fields, and only selected custom fields: $pageFields = new PageFields($p, [ 'fld_core_included' => [], 'fld_include_all' => false, 'fld_included' => ['title', 'gallery'], ]); On a gallery image field, hide breakpoint listing and show only httpUrl field: $pageFields = new PageFields($p, [ 'img_fld_overrides' => [ 'gallery' => [ 'fields' => ['httpUrl'], 'bp_list' => false ] ], ]); Webpack setup The most important file of all Webpack setup is config/index.js. On line 33 you need to provide your domain name so that Webpack can proxy the ProcessWire REST API to the Webpack dev server. Without this you wouldn't be able to take advandage of the Webpack hot module replacement feature which allows you to reload a vue module without refreshing the page, it also allows you to keep the state of the app. Notes My REST API may have bugs, this is just an example of an integration with ProcessWire, I suggest you either build your own REST API or use the awesome GraphQL module by @Nurguly Ashyrov. Todo Replace REST API with the GraphQL module. This requires vue-apollo, the Apollo/GraphQL integration with Vue, and vue-supply for integration with Vuex.
    1 point
  19. My bad! That's what happens when you type just before dashing out the door . As @adrian shows above, it should be InputfieldMarkup. There's a couple of examples in the Blog module link I posted above. Note that since the method is static in the blog case, we use this instead: $m = new InputfieldMarkup; $m->label = __('Blog fully installed'); // blah blah $form->add($m); Guilty as charged sir! Ditto - the rushing out the door . Corrected the links, ta.
    1 point
  20. I know this is an old thread, but if someone finds this, I also would absolutely recommend this module if you're working with tagging pages: I use it on pwtuts.com and it makes it very easy. In the footer of the aforementioned site, there is a tag list, which is pulled from this file /includes/tags-list.php: <?php namespace ProcessWire; ?> <h2>Tags / <a href="/tags/">See all</a></h2> <ul class="tag-block list-unstyled"> <?php $tags = $pages->get("/tags/")->children; foreach ($tags as $tag): if (count($tag->blogPosts)): ?> <li>#<a href="<?= $tag->url; ?>" class="<?= $tag->name; ?>"><?= str_replace("-", "", $tag->name) ?> (<?= $tag->blogPosts->count ?>)</a></li> <?php endif; endforeach; ?> </ul> ...because the blogPosts fields are connected to the tags, it's just a case of using count() on the tag i.e. if it has page ref fields (blogPosts), print them. Count is used again to output how many posts are associated with each tag. This would have been more awkward for sure without this module, you'd have to get each tag, then find the number of posts that have that tag etc...
    1 point
  21. It's really easy to customize the admin to however you want it to look. I think I may write a tutorial about how to do this. Just need nodejs/npm, create a single (your theme) .less file, import it to _imports.less, and use their included build script.
    1 point
  22. Markup is what I do: $f = $this->wire('modules')->get("InputfieldMarkup"); $f->attr('name', 'config_intro'); $f->label = ""; $f->value = "<p>These settings will override those in the main config settings for this page.</p>"; $fieldset->append($f); I think you'll need lowercase "markup" using that approach to field configuration.
    1 point
  23. Hey @kongondo - I am OT here and not meaning to single you out I was going to PM you, but thought I could make this a friendly public service reminder to hit the "Y" key in Github before posting links to a line of code so they will be correct even after changes to the file. Thanks everyone!
    1 point
  24. .InputfieldHeader { padding: 10px 10px 10px 20px; } .InputfieldStateCollapsed > .InputfieldHeader { padding-bottom: 10px; } remember that the minimum size for an element in a touch device should be 44 pixels, these padding values are the minimum values that you must use in the processwire header to comply with that rule..
    1 point
  25. Well, today you'd use lazy-loading techniques (load 20 items on load, and then 20 more with "show more" etc.), therefore eliminating the need for classic pagination, or show the current page-set in the URL. With endless scrolling and pagination, you could try something like this: https://elkfox.github.io/Ajaxify/ Ajaxination - Normal pagination style but load the page without reloading, uses push states.
    1 point
  26. If using the old style, what you need is the method getModuleConfigInputfields(). I think it used to be a static method so no $this, etc, but that could have changed at some point I. Here's how we do it in the Blog module (static method). For that specific case we jump through a couple of hoops but it need not be that complicated in normal use. You can also look at other examples to get the gist of it (e.g. Tracy, [non-static method] and some core modules. Invariably, these will be Process modules, e.g ProcessPageSearch.). Your module will have to implement the ConfigurableModule interface. The Module interface is a good read.. In the links above, see also the code for retrieving saved values. Here are some old links on this topic: Possibly related Edit: see next post if you already know above; my bad; just re-read your post.
    1 point
  27. @adrian, thanks issue solved have to consider upgrading to 3.0.84.
    1 point
  28. Nice one! I have a small issue with the navbar on my MacBook Pro 13" :
    1 point
  29. You only made a simple statement there. Where are your arguments ? We had this django talk already a couple of days ago in this thread. https://processwire.com/talk/topic/17852-processwire-vs-django/
    1 point
  30. Additionally, you don't need a PayPal account - you can pay with your CC without signing up. I am not defending PayPal - I actually think it's a pretty ugly system to use, but it does mostly get the job done however you need. You'll always have more flexibility with other services though. In Canada, Moneris is a reasonable option - not modern like Stripe etc, but it can be completely hidden from the user - ie everything happens on your site with no redirect.
    1 point
  31. @erikvanberkum I just tested on 3.0.60 (I didn't have easy access to 3.0.62 using the PW Version switcher ) and I can actually reproduce the issue you are having. Turns out it's a bug in the PW core in that version. Look at the difference between: 3.0.60 if($languages) $languages->setLanguage($language); 3.0.84 if($languageID) $languages->setLanguage($language); I would recommend upgrading to 3.0.84 to fix the problem! PS - in my experience, 3.0.84 is more stable than the current "stable" version.
    1 point
  32. @adrian Replacing this code makes it work again. Now I am able to enable and disable Tracey. if($languageID) { echo 'test' . $language->name; //$languages->setLanguage($language); } I cant find the output from the echo test, language name. The default language in my installation is English. I only have the error when i enable or disable the Tracey. When its enabled and I remove the above code it keep working properly.
    1 point
  33. 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
  34. 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!
    1 point
  35. Adrian Upgraded from to 4.8.11 today but problem stays i am running PW 3.0.62 on PHP 7.0.22-0 on an ubuntu0.16.04.1 echo $languageID before line 813 returns a 0 i have a total of 4 languages installed on this instance. Any ideas for further investigation?
    1 point
  36. I usually go for a modular layout. You take a repeater, and add all the fields you'll need for all types of content block: body, title, images, etc. You add another field called type, make it an options field, and get in there all the types of block you need. Text, image gallery, video... whatever. Then you customise each field's visibility to appear only when type=1, for example. That will allow the admin to freely add a chunk of text, then a gallery, then more text... No weird tags to remember, simple and straightforward. On the frontend, you make include files for each type (remember the options field) to keep it neat and tidy, foreach the repeater, and include() the correct block template file according to the value of the type field. Generate away.
    1 point
  37. 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.
    1 point
  38. @diogo, Actually, my mouse stopped registering wheel scrolls a few weeks ago. On the positive side, I still have a middle button! Enabled the laptop pad and can scroll just fine with it. Wacom tablet doesn't scroll.
    1 point
  39. @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.
    1 point
  40. Hello Adrian upgraded to the latest version and i didnt go well, i am unable to enable the plugin: ProcessWire: ProcessModule: Unknown language DEBUG MODE BACKTRACE ($config->debug == true): #0 /var/www/html/wire/core/PagesLoader.php(813): ProcessWire\Languages->setLanguage(NULL) #1 /var/www/html/wire/core/Pages.php(719): ProcessWire\PagesLoader->getPath(21, Array) #2 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/TracyDebugger.module(2662): ProcessWire\Pages->getPath('21') #3 /var/www/html/wire/core/WireHooks.php(777): TracyDebugger->{closure}(Object(ProcessWire\HookEvent)) #4 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Modules), 'saveModuleConfi...', Array) #5 /var/www/html/wire/modules/Process/ProcessModule/ProcessModule.module(1309): ProcessWire\Wire->__call('saveModuleConfi...', Array) #6 /var/www/html/wire/modules/Process/ProcessModule/ProcessModule.module(1136): ProcessWire\ProcessModule->renderEdit('TracyDebugger', Array) #7 /var/www/html/wire/core/Wire.php(380): ProcessWire\ProcessModule->___executeEdit() #8 /var/www/html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___executeEdit', Array) #9 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessModule), 'executeEdit', Array) #10 /var/www/html/wire/core/ProcessController.php(244): ProcessWire\Wire->__call('executeEdit', Array) #11 /var/www/html/wire/core/Wire.php(380): ProcessWire\ProcessController->___execute() #12 /var/www/html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___execute', Array) #13 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessController), 'execute', Array) #14 /var/www/html/wire/core/admin.php(113): ProcessWire\Wire->__call('execute', Array) #15 /var/www/html/wire/modules/AdminTheme/AdminThemeReno/controller.php(13): require('/var/www/html/a...') #16 /var/www/html/site/templates/admin.php(15): require('/var/www/html/a...') #17 /var/www/html/wire/core/TemplateFile.php(268): require('/var/www/html/a...') #18 /var/www/html/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render() #19 /var/www/html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___render', Array) #20 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array) #21 /var/www/html/wire/modules/PageRender.module(514): ProcessWire\Wire->__call('render', Array) #22 /var/www/html/wire/core/Wire.php(383): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent)) #23 /var/www/html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___renderPage', Array) #24 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\PageRender), 'renderPage', Array) #25 /var/www/html/wire/core/WireHooks.php(782): ProcessWire\Wire->__call('renderPage', Array) #26 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Page), 'render', Array) #27 /var/www/html/wire/modules/Process/ProcessPageView.module(205): ProcessWire\Wire->__call('render', Array) #28 /var/www/html/wire/core/Wire.php(383): ProcessWire\ProcessPageView->___execute(true) #29 /var/www/html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___execute', Array) #30 /var/www/html/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessPageView), 'execute', Array) #31 /var/www/html/index.php(55): ProcessWire\Wire->__call('execute', Array) #32 {main}
    1 point
  41. $config->urls->root should usually return "/" Maybe you are looking for $config->urls->httpRoot Or maybe you need to deal with htaccess redirects - in which case, uncomment the lines under section 13 of the .htaccess file.
    1 point
  42. @dragan, you can add the inputfield like this: $wire->addHookAfter('ProcessPageAdd::buildForm', function(HookEvent $event) { $form = $event->return; // If adding page under particular parent if($this->input->parent_id === '1234') { // Add inputfield to form after existing title field // If you name the inputfield the same as the field you want to populate // then the entered value will be saved automatically $f = $this->modules->InputfieldText; $f->name = 'vertec_code'; $f->label = 'Vertec-Code'; $f->required = true; $f->attr('required', 1); // use HTML required attribute too $title_field = $form->getChildByName('title'); $form->insertAfter($f, $title_field); $event->return = $form; } }); Because of this section in ProcessPageAdd::processInput, if you name the inputfield the same as the corresponding field in the template of the new page then the entered value will automatically be saved to the page.
    1 point
  43. et voilà - I made a little mock-up
    1 point
  44. Not sure if this is due to any changes in this specific version, but I’m not able to upload images (tested in a user profile). It returns with Invalid POST Data. Upon further investigation, it seems to come from this: /wire/modules/Process/ProcessProfile/ProcessProfile.module (line 213) When uploading the image, it sends a post request to /admin/profile/?InputfieldFileAjax=1, with the following headers: X-FIELDNAME:image X-FILENAME:6.png X-REQUESTED-WITH:XMLHttpRequest The user ID doesn’t appear to be set in the request, which is why the error is thrown. Interestingly, the HTTP code returned is 200… After that request, another is made to blob:http://domain.lserv/aa5ddd22-6dbf-42e0-9d12-1cee83b8fb39, which returns the image I uploaded, yet it does not exist in the files directory. (Honestly, I don’t know how AJAX uploads work behind the scenes, so this part of it could well be by design…) Is there something further I need to do, or is this a geniune bug that needs reporting?
    1 point
  45. Hm, I don't consider this as an issue, rather personal preference or maybe annoyance, that can be dealt with a few css tweaks, although I didn't attempt to do it (yet), waiting for more experienced CSS developers
    1 point
  46. Agree. We all love space to breath, but in this case this is just too much. Especially those notices are annoying with their height. On the other hand, this is just default theme, waiting to be "pimped" ... +1, Let's file an issue report
    1 point
  47. hi abdus, thanks for your effort on helping others maybe i can suggest you to take a tool that lots of people are using here for creating micro-screencasts as animated gifs: http://www.cockos.com/licecap/ very easy, very helpful
    1 point
  48. First of all, create a template called "tags". It is totally fine to leave as it is, just a "title" field, no need for a PHP-file (for now). To be sure, only allow children with template "tags" in the template "family" tab. Then create your hidden "tags" page. Put same tags in it (that means: create children pages with your tags as title) if you like. Correct. Template for selectable pages is "tags". You can also define your hidden tags page as parent. No template file needed (for now). Not necessarily. or from the page select field itself (very convenient). So for that you need to have a .php file as template for the template "tags". First, create your tag list like this: echo "<ul>"; foreach($pages->get('/tags/') as $tag){ //iterate over each tag echo "<li><a href='{$tag->url}'>{$tag->title}</a></li>"; // and generate link to that page } echo "</ul>"; (totally untested, but you'll get it). Since the tag pages have no template yet, this will throw an empty page (or 404, don't know). So let us create a template for the tag pages, which lists all pages with that tag: // Beginning of your template here (head etc.) // select all pages with the tag of this tag page $thisTag = $page->title // Current clicked tag $tagPages = $pages->find("Tags.title=$thisTag"); // select all pages where page field "Tags" contains a page with title of our tag foreach ($tagPages as $tp){ // iterate over the pages with that tag // and generate some teasers (or what you like) echo " <div class='teaser'> <h3>{$tp->title}</h3> <p>{$tp->summary}</p> <a href='{$tp->url}'>Read more...</a> </div>"; } // Rest of your template here (footer, javascripts etc.) as I said, totally untested, but this should point you in the right direction.
    1 point
  49. MIGRATING A SITE FROM DEV TO LIVE FOR THE FIRST TIME STEP 1: Copy all the files from dev to live Copy all the files from your dev installation to the live installation. Whether you use FTP, rsync, scp or some other tool doesn't matter. What does matter is that you copy everything and that you retain the file permissions–More specifically, make sure that /site/assets/ and everything in it is writable to the web server. Here are some sample commands that would do it (replace 'local-www' and 'remote-www' with your own directories): Using rsync: rsync --archive --rsh=/usr/bin/ssh --verbose /local-www/* user@somehost.com:remote-www/ Using scp: scp -r -p /local-www/* user@somehost.com:remote-www/ Using FTP/SFTP/FTPS: I think this will depend on the FTP client that you are using as to whether it will retain the permissions of the files you transfer. Hopefully it will do that by default, if not, check if there is a setting you can enable. If not, then you may have to adjust the permissions manually in /site/assets/ and the dirs/files in there. Make sure /.htaccess got copied over too Depending on how you copied the files in step 1, it may or may not have included the /.htaccess file. Make sure that gets copied over, as many copying tools will ignore hidden files by default. STEP 2: Transfer the MySQL Database from Dev to Live a. Export dev database Export ProcessWire's database on your development server to a MySQL dump file. PhpMyAdmin or mysqldump are the most common ways to do it. Personally I use PhpMyAdmin because it's so simple, but here is how you would do it with mysqldump: mysqldump -u[db_user] -p[db_pass] [db_name] > site.sql b. Create live database Create a new MySQL database and database user on the live server and make note of the DB name, DB host, DB user and DB pass, as you'll need them. c. Import dev database to live Import the MySQL dump file you exported from your dev server. Most web hosts have PhpMyAdmin, so that's what I use to import. If you have SSH access, you can also import with the mysql command line client, i.e. mysql -u[db_user] -p[db_pass] -h[db_host] [db_name] < site.sql d. Update /site/config.php On the live server, edit the /site/config.php file. At the bottom you will see the database settings. Update these settings to be consistent with the database/user you created, then save. Most likely you will only be updating these settings: $config->db_name = "database name"; $config->db_user = "database user name"; $config->db_pass = "database user password"; $config->db_host = "database host, most commonly localhost"; STEP 3: Test the Site Your site should now be functional when you load it in your browser. If not, then enable debug mode: a. Turn on debug mode (only if you get an error) Edit /site/config.php and look for $config->debug = false, and change it to $config->debug = true. Then load the site in your browser again and it should give you more details about what error occurred. If you aren't able to resolve it, contact Ryan. b. Browse the site Assuming your site is now functional, browse the site and the admin and make sure that everything looks as it should. If it looks like stylesheets aren't loading or images are missing, it may be displaying cached versions from your dev site. If that's the case, you need to clear your cache: c. Clear your cache (optional) Login to the ProcessWire admin and go to Modules > Page Render > and then check the box to "clear page render disk cache", then click save. This should resolve any display issues with the site's pages. d. Practice good housekeeping Make sure that you've removed /install.php and /site/install/, and check to make sure that /site/config.php is not writable. While this isn't absolutely necessary, it's good insurance.
    1 point
×
×
  • Create New...