Jump to content

kongondo

PW-Moderators
  • Posts

    7,529
  • Joined

  • Last visited

  • Days Won

    161

Everything posted by kongondo

  1. Thx folks! I must have skimmed over the docs too quickly. I saw neither of 'expand' nor the '@' class :-).
  2. Ok, so CSS is not my thing, but even by my (very low) standards, surely this ought to be rudimentary. I feel silly creating a whole thread for this but for the life of me, I'm unable to create a simple 3-column grid using ui-kit! The first and the third columns need to be 15% (or even 25%) in width each. The column in the middle should take the remainder. I've done the width thingy/class (ui-kit-width-blah-blah) , nesting 3 divs inside a parent div but it just wont play ball. The 3rd child div is collapsing to the next row. Please don't roll your eyes at me; I'm a noob :D. Help, anyone? Thanks.
  3. Hi @Mustafa-Online. I've posted an answer in your original thread.
  4. You can Hook into InputfieldFile::processInputFile. There are other places in that Class you could also hook into, but I think processInputFile works best. Throw the code below in ready.php Please note: Starter code: not much validation going on other than checking if the field the file was uploaded to is 'course_file' You will have to implement other logic yourself. For instance, the code copies the file immediately it is uploaded by ProcessWire Ajax. It doesn't check if the page is actually saved. If a page is not saved and the page is reloaded, as you know, files in file fields are deleted from disk. This code does not delete the corresponding file in your custom directory You might want the Hook to only run if you are in admin. You can add that logic I've purposefully left in verbose and debugging code in there (Tracy stuff) to help you ( maybe and others) understand what's going on. I suggest you test using Tracy Debugger for a better grasp of the file upload process. Delete the debugging stuff when you've got this working as you want :-). wire()->addHookAfter("InputfieldFile::processInputFile", function(HookEvent $event) { // @note: here, events are $input, $pagefile, $n @see: the method // get event we are hooking into // get arguments by index {a bit faster, but less-readable} /* $input = $event->arguments[0]; $pagefile = $event->arguments[1]; $n = $event->arguments[2]; */ // get arguments by name #$input = $event->argumentsByName('input'); $pagefile = $event->argumentsByName('pagefile'); #$n = $event->argumentsByName('n'); // $pagefile->field: The Field object that this file is part of. // limit to a specific field {course_file} if($pagefile->field->name != 'course_files') return; # intercept file // Tracy Debugger calls to see what's going on. Also logs Ajax inputs! #bd($input, 'input'); #bd($n, 'input'); // @see: http://processwire.com/api/ref/pagefile/ // pagefile object bd($pagefile, 'pagefile'); // name of the field uploading to {your 'course_file'} bd($pagefile->field->name, 'field pagefile is part of'); // file-sanitized name of the file we've added, e.g. 'checklist_install.pdf' bd($pagefile->basename, 'name of added file'); // full disk path where the file has been uploaded in this page's files folder... //... in /site/assets/files/1234 where 1234 is this page's ID // ... e.g. "F:/www/mysite/site/assets/files/1234/checklist_install.pdf" bd($pagefile->filename, 'full disk path name of added file'); // $pagefile->page: The Page object that this file is part of bd($pagefile->page->id, 'id of the page file added to'); // full disk path to your custom uploads directory $customDirectory = $this->wire('config')->paths->assets . 'custom_directory/'; bd($customDirectory,'custom directory for files'); # copy file // use ProcessWire's $files API // @see: http://processwire.com/api/ref/files/ $files = $this->wire('files'); // copy the file(s) $files->copy($pagefile->filename,$customDirectory . $pagefile->basename); });
  5. Hi Keith, Would love to see your site when it's done. Hope you are keeping well. /k
  6. What @AndZyk said. Below is one way to do it. Before that though, logic whether something exists should really be done server-side. Yes, you can also do client-side checks the way you are doing it (just for UX) as long as you also validate things server-side. Otherwise, if you only do it client-side, it is easy to change the 'valid until date' of the coupon in the markup and send that to the server which would honour the coupon and you'd incur a loss in your takings :-). I hope you are also checking server-side. OK, here's the code. It makes things cleaner, more readable and is less prone to mistakes since PHP handles the JSON string. <?php // initialise variables $couponsArray = array(); $couponsJSON = ''; // fetch coupons $coupons = $pages->find("template=paddiscount, title!='', pad_percentage!=''"); // we found coupons if($coupons->count) { // loop through coupons and add values to coupons array foreach($coupons as $coupon) { // if coupon valid until, get human readable valid until date, else empty $couponValidUntil = $coupon->pad_valid_until ? date("Y-m-d", $coupon->pad_valid_until) : ''; $couponsArray[$coupon->title] = $couponValidUntil; } // generate JSON string of coupons for JavaScript $couponsJSON = json_encode($couponsArray); } ?> <!-- html here --> <script type="text/javascript">var coupons = <?php echo $couponsJSON ?></script> Then in your JavaScript do your checks, if var coupons is not empty, etc. Hope this helps :-).
  7. Maybe I am not reading this correctly, but why do you need a Hook? The code is from the default site profile that ships with ProcessWire: <?php if($user->isLoggedin()) { // if user is logged in, show a logout link echo "<a href='{$config->urls->admin}login/logout/'>" . sprintf(__('Logout (%s)'), $user->name) . "</a>"; } else { // if user not logged in, show a login link echo "<a href='{$config->urls->admin}'>" . __('Admin Login') . "</a>"; } ?> Or maybe you mean you want them to login from a page other than the admin page?
  8. I'm using the core ProcessWire image field, so no. All, Anyone knows what's going on here?
  9. I've noticed that as well. I think that's weird. Maybe a bug or a cache issue in ProcessWire? I've not seen this behaviour before. I've been able to get rid of the 'blank references to deleted images' by deleting them in the page editor.
  10. Sorry again. Saturday night! My bad. Call this before delete $p->of(false); I edited my post above as well.
  11. ? Does the code not work?
  12. Oops, my bad. You need to save the page as well. Do this after and outside the foreach. So $p->save() as shown below. <?php include('./_head.php'); // include header markup ?> <?php if($user->isSuperuser()) { $p = $pages->get(1029); // delete some images based on some condition foreach ($p->images as $img) { if($img->filesize<300000) continue;# if some condition met, skip deleting this image echo $img->name.'wird gelöscht<br>'; $p->images->delete($img); } // set page output formatting off first $p->of(false); // save page 1029 to effect changes $p->save(); // if deleting all #$p->images->deleteAll(); } ?> <?php include('./_foot.php'); // include footer markup ?> note: code edited
  13. Awesome! I really need to get some time to test it! This topic should be marked as [almost solved], eh? ;-). Read @bernhard tutorial on Process Modules and use his RockGrid module ?
  14. Here's something to chew on. Start with this tutorial: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ Some code to play with. This creates a paginated ProcessWire-rendered HTML table. Create a module as per above tutorial. Use the following code in your Process module's execute() method. You need to create some people pages. In this example, they use the template 'people'. Edit functionality not included. Have a look at Blog module for that, here. For CSV upload (not included), have a look at Matrix module here for uploading CSV file and here for reading CSV file. /** * Display, Add and Edit People. * * Called when the URL is peoples's page URL + "/people/" i.e. URL Segment. * Renders a table with People information. People can be edited via modal. * * @access protected * @return mixed $form rendered form * */ public function ___execute() { $modules = $this->wire('modules'); $input = $this->wire('input')->post; $pages = $this->wire('pages'); // CREATE A NEW FORM $form = $modules->get('InputfieldForm'); $form->attr('id', 'people'); $form->action = './'; $form->method = 'post'; // CREATE AN INPUTFIELD MARKUP: Will hold list of people table $m = $modules->get('InputfieldMarkup'); $m->textFormat = Inputfield::textFormatNone;// make sure ProcessWire renders custom HTML // $m->label = $this->_('Edit'); // $m->description = $this->_('Click on a title to edit the item.'); // CREATE A NEW TABLE: for people $t = $modules->get('MarkupAdminDataTable'); $t->setEncodeEntities(false); $t->setClass('peopleTable'); // set header rows $peopleTableHeaders = array( '<input type="checkbox" class="toggle_all">', $this->_('Title'), $this->_('Name'), $this->_('Surname'), $this->_('Another Column'), $this->_('One More Column'), $this->_('Published'), #$this->_('Date'), ); $t->headerRow($peopleTableHeaders); // grab a limited number of people to show in people dashboard. Limit is hardcoded in this example $people = $pages->find("template=people, include=all, sort=-created, parent!=7, limit=10"); foreach ($people as $p) { if (!count($people)) break;// if no people found, break early // check if person page is published or not $p->is(Page::statusUnpublished) ? $status = '<span class="unpublished">' . $this->_('No') . '</span>' : $status = $this->_('Yes'); // set table rows $peopleTable = array( "<input type='checkbox' name='posts_action[]' value='{$p->id}' class='toggle'>",// disabled sorting on this in .js file "<a href='{$this->wire('config')->urls->admin}page/edit/?id={$p->id}&modal=1' class='editPeople pw-modal pw-modal-medium'>$p->title</a>", $p->title, $p->person_name, $p->person_surname, $p->another_column, $p->one_more_column, $status ); // render the table rows with variables set above $t->row($peopleTable); }// end foreach $people as $p // display a headline indicating quantities. We'll add this to people dashboard $start = $people->getStart()+1; $end = $start + count($people)-1; $total = $people->getTotal(); if($total) $peopleCount = "<h4>" . sprintf(__('People %1$d to %2$d of %3$d'), $start, $end, $total) . "</h4>"; // add a description to people dashboard {postsCount, limitSelect and instruction OR no people found status} $m->description = $total == 0 ? $this->_('No items found.') : $peopleCount . $this->_('Click on a title to edit the item.'); $m->notes = "People table notes"; $currentUrl = $this->wire('page')->url . $this->wire('input')->urlSegmentsStr."/";// get the url segment string. In this case it is "people" $pagination = $people->renderPager(array('baseUrl' => $currentUrl)); $m->attr('value', $pagination . $t->render() . $pagination);// wrap our table with pagination $form->add($m); $post = $this->wire('input')->post; // render the final form return $form->render(); }
  15. Luke, the reason am asking particular questions is so that we can offer a tailored response. Without more information, it is difficult to offer a specific answer. For instance, I asked, how many columns in the database? But it seems to me you now want to go with pages, as per our suggestion, right? Assuming you are going with pages. Display Your process module, in its execute function (I am assuming you've read about this?) will render your HTML table. You can either render a ProcessWire table, or your own custom HTML table, or use Process Lister or RockGrid. All of this can be paginated so that only a limited number of people are loaded at a time. See Process Blog module for displaying pages in a HTML table. In the HTML table, do you want to display all data columns (e.g. name, surname, fiscal thingy, etc) OR do you want to display only full name (i.e. Steve Job?) Modal Then when client clicks on Steve Job, it opens a modal to the Steve Job page. The Steve Job page has several fields for name, surname, fiscal thing, etc. The client edits the fields he wants and closes the modal The page reloads (or if using ajax, only the data reloads) See Blog module (Process blog for opening pages in modal for editing) Note: Since the pages are in admin, we will have to by-pass user access check in order for client to edit the page Uploading new 'people' We have a button or file field for uploading new people data as CSV (see my FieldtypeMatrix module for example) When the csv file is uploaded, a script loops through it and creates people pages on the fly, mapping csv columns data to the ProcessWire page's fields. Before creating a page we check if there is already a people page with similar data {same email, same name, same surname, etc} You then decide what you need to do; update if duplicate found or skip creation of that people page? People page reloads (or ajax refresh) These are ideas, but very doable. But we need specific answers to our questions. You never know; someone might just create a draft module for you ?
  16. Yeah, what @flydev said. Pages is the easier route in your case. We are not saying it cannot be done by using your custom database and querying it directly. That's possible, but in your case, a lot more technical work. Your client does not have to see the tree of people pages. You can have those hidden under a single parent whose parent is /admin/ rather than home (/). This way, only superusers can see the people tree. With a Process Module, you don't have to be visiting the page tree even as a superuser. You only need to know that they are there and the evidence is that you can see them in your Process Module :-). The 'each person is a page' approach means that ProcessWire does all the heavy lifting, dealing with databases operations. Heck, your Process Module will allow you to filter users or sort them according to some column. Your database columns, depending on the data, can either be stored as single ProcessWire fields - name=text;surname=text,other_data=integer, etc OR as one blob of JSON text in a single text field, which can be retrieved and turned into an array. We need to see the column names and how many you got, to give a definite answer. How has your client been updating the database in the old website? You still haven't told us how soon you need this ?
  17. Is the client going to type in the data one by one or are you importing from a file, .e.g a CSV or JSON file? How many people potentially in the datasheet? Will this be done once or will the people be regularly updated? Can the people be saved as pages (hidden in admin) or you'd rather have them in a table external to ProcessWire? Manage People Datasheet You might need to create a simple Process Module, maybe even a one pager that lists the 'people'. You can include some simple actions like delete or edit people. To add people, a click on some button could open a modal window for you to add a person (depends on whether you are importing a file of people or typing manually). There's also the module RockGrid that you can use for listing the 'people'. I don't know if it can do data imports though. I think it works with ProcessWire pages only, but am not sure. User registration Since creating users is a manual process, you have a lot of control here. How you check if a user is on the allowed people list depends on the approach you take above, i.e. whether people are pages or are in a custom database. If they are pages, you can use $pages API, e.g. $newUser = $pages->get("template=people, first_name=$firstName,last_name=$lastName"); Then check if that returned something. If yes, register this user. If you are using a custom table, you'd need to use SQL to fetch, insert, update, etc, people. ProcessWire has a $database API that you can use Your other option is a custom Fieldtype but that is a bit more technical, going by how you've described your current skill set. Depending on your timescales, you might be able to get some help in the forums. If this is needed fairly soon, you might want to consider hiring an experienced ProcessWire developer to carry out the work for you.
  18. Thanks @adrian. I was looking for that one but couldn't find it. I had a feeling I'd read about it somewhere. How would it work in this case, just throw in the page ref field in the selector part?
  19. $faqs = $pages->find("template=template-of-faq-pages, page_ref_field_of_faqs=$page, limit=10"); we are limiting to 10 hits in this example.
  20. Use the API :-). Log in as a super user and throw the following code in some template file and visit a page that uses that template. Delete the code from the template file when done. if($user->isSuperuser()) { $p = $pages->get(1029); // delete some images based on some condition foreach ($p->images as $img) { if($someCondition) continue;# if some condition met, skip deleting this image $p->images->delete($img); } // if deleting all #$p->images->deleteAll(); } Alternatively, use the API to create thumbs in the size ProcessWire would have generated.
  21. ?. Yeah. What @adrian said. PHP is most likely running out of memory when ProcessWire tries to create thumbs for those images. Second time round, they should load fine (assuming the thumbs creation finished). Maybe also see if you need to rethink your approach? 300 images on one page, from a UX point of view can be 'not-so-friendly'?
  22. Glad you got it sorted ?
  23. Hmm. More Intelephense quirks. This extension just doesn't want to work on my system. If I hover over a variable, I expect it to show me (peek preview) the value of that variable as initially set. It doesn't do this. At times it shows the variable type at times it shows nothing. With PHP IntelliSense, it works every time. I get these on hover.
  24. What tool is that, btw?
  25. Hi @derelektrischemoench, This code: $targetPage = $pages->get($menuItem->id); is the problem. For objects returned by getMenuItems(), id refers to the internal menu item ID in the collection AND NOT the corresponding ProcessWire page ID :-). Apologies, documentation could be clearer. To get the ProcessWire page ID of that menu item, use pagesID instead. So: $targetPage = $pages->get($menuItem->pagesID); By the way, please note that menu items with a pagesID of 0 are external menu items (e.g. an item pointing to google.com, etc). And while we are here.. This: $targetPage->get('images'); Could be changed to: $targetPage->images; However, your code shows that you are returning the whole 'images' field object. That is why you see this: ["pictures"]=> object(ProcessWire\Pageimages)#235 (2) { ["count"]=> int(1) ["items"]=> array(1) { ["steinlampe_2_grayscale.png"]=> string(26) "steinlampe_2_grayscale.png" Is that intentional? Aren't you really after the url of the image? Secondly, how many images are in each menu item's images field? Is the image field a multi image field or single? If multi, you need to loop through it if you want multiple images from it, or get the first one using first(). If it is a single image field, you are fine, you can just grab the URL.
×
×
  • Create New...