Jump to content

BitPoet

Members
  • Posts

    1,312
  • Joined

  • Last visited

  • Days Won

    60

Posts posted by BitPoet

  1. 22 hours ago, poljpocket said:

    You must create your own database schema and save your data there if that is what you are after.

    As an alternative, but which also involves some coding: you can also create fields + fieldgroup + template + a "storage" page in your module's install method. Then, in your processForm method, you can fetch that page and assign the form values there, or you just display a modal link to the page editor in your buildForm method and let PW take care of saving the values. That approach can get a bit involved (double so if you want to clean up in your uninstall method), but it can have some advantages (retaining the values after module uninstall, straight forward use of arbitrary field types).

  2. 1 hour ago, da² said:

    In my current project I sometimes import 5000 pages using PW API, and with transactions (wire()->database->beginTransaction(); wire()->database->commit();) it is done in 20-30 seconds.

    It should be faster with transaction, and I did add startTransaction and commit in my import script. I'm still trying to figure out where the bottleneck is. Shouldn't be the hardware (i9-14900K, 64GB, high speed NVMe SSD), and I didn't see any io waits in the stats, so something is probably wrong with my db server (MySQL 8.4.0 on Windows 11). Looks like I've got do some forensics there.

    • Like 2
  3. 8 hours ago, wbmnfktr said:

    The most fun part until now was to realise that importing 50k items is something different than handling 50k items that grew over years. A nice reality check.

    Yep. About 24 hours on InnoDB for a full import. More that 52k books, 983 genres, 48k characters, 10k publishers, 15k awards. All in all 95314 pages in an otherwise pristine PW installation.

    I'm attaching a site profile with the data if someone wants to play around.

    site-bookinventorydata.zip

    • Like 6
  4. On 8/9/2024 at 11:39 PM, ryan said:

    MySQL can also support this with JSON encoded in a more traditional TEXT column with some reduced efficiency, though with the added benefit of supporting a FULLTEXT index. (Whereas the JSON column type does not support that type of index). For this reason, FieldtypeCustom supports both JSON and TEXT/MEDIUMTEXT/LONGTEXT column types. So you can choose whether you want to maximize the efficiency of column-level queries, or add the ability to perform text matching on all columns at once with a fulltext index.

    Just a thought for future in case performance really becomes an issue for someone: it's possible to add a generated + stored column to a MySQL table that feeds itself from a dedicated value in a JSON column, and this column can of course have a fulltext index. A hook on PageFinder::getQueryUnknownField could then "redirect" the query to the generated column. Would only work on single valued fields, of course.

    For anybody interested in creating such a generated field from a JSON field, here's a blog entry that explains it better than I could.

    • Like 8
  5. 37 minutes ago, adrian said:

    I have a check to make sure the integrity of some page reference fields (selected staff on client accounts) and I need to make sure if a staff member is unpublished that a warning is given.

    I'd probably approach that with a hook on User::unpublished, perform the checks there whether the user is staff and referenced from a client account, and send a message (through PW's message system or even other means like a ticket system or email).

    • Like 1
  6. It seems that I'll have to rename the module if I really decide to pursue developing it (which I doubt more and more). rtf.js unfortunately can't deal with the different dialects of RTF. I've removed the dependency and hacked together a pretty dirty regular expression that extracts image data from the RTF clipboard contents, then looks for img tags in the HTML contents and replaces the src for every found image with the extracted images in the same order. Whether that is practicable outside of my simple test cases is up for discussion. So far, the images always came in the same order in both formats.

    I'm currently only extracting PNG and JPG and insert a placeholder for others. I'm beginning to understand why TinyMCE's PowerPaste plugin is commercial.

  7. Since it came up in this question and I had some time to kill in front of my computer waiting for updates to finish which I had to verify, I got curios whether copy & paste from Word on Windows into a TinyMCE editor field could be made to insert the formatted text and keep the images. Surprisingly, with the help of rtf.js, this went pretty quickly. Ryan already built automatic upload functionality (called ImgUpload) into the TinyMCE field, so I only had to enable the option and select a target field.

    Even though pasting word processor generated HTML is and always has been a sin, I built a small module for it anyway. I called it (I know, it sounds a bit clunky, but it was the best I could come up with, I'm a backend guy):

    RtfPasterTinyMce

    Usage

    • Download the contents of this repository and unpack into a folder in site/modules
    • Open ProcessWre admin and select Modules -> Refresh
    • Click "Install" for "Rtf Paster TinyMCE"
    • Go to "Fields" and select your TinyMCE field where you want to paste office content including images
    • Check "rtfpaster" in "Additional plugins" on the "Input" tab and save your field configuration
    • Edit a page with that field and copy a passage that contains both text and images from MS Word into your TinyMCE field. You should see your images there.

    Advanced

    • Go into InputfieldTinyMCE's module settings and enable "Image fields for ImgUpload"
    • Edit your TinyMCE field and select an existing image field in the "Image fiels for ImgUpload" select on the Input tab
    • Paste some text / images mixture from your word processor MS Word

    Tadaa! Your images are magically uploaded into the selected field.

    Since the RTF doesn't contain any information about the file name of the source image, your uploaded images will be named fieldname.png, fieldname-1.png, fieldname-2.png etc.

    Keep in mind that this is so far a proof-of-concept module and hasn't been tested with different scenarios and source applications yet. Don't use it in production unless you feel confident to fix any errors yourself!

    Edit: Only successfully tested with MS Word. Not working with LibreOffice's RTF.

    • Like 6
  8. Out of curiosity, I've created a small proof-of-concept module/plugin for InputfieldTinyMCE. If activated, it tries to fetch RTF clipboard content, parse that to HTML (with images as data: URLs) and insert the result, overriding TinyMCEs default paste behavior. I only did a small test so far. Maybe you'd like to do a test drive.

    https://github.com/BitPoet/RtfPasterTinyMce

    It uses https://github.com/tbluemel/rtf.js for the heavy lifting.

    Edit: forgot to say: this could of course be expanded to extract the image data, upload that to a dedicated image field through PW's standard upload endpoint and use the URL of the uploaded image in the inserted HTML.

    • Like 1
  9. Pasting from office applications is a complicated topic. The Windows clipboard can offer different formats of its contents to applications you paste to, e.g. plain text, HTML or image data, or different other data formats both the application you copy from and the receiving application have registered with the Windows system. In the case of copying from Word, your clipboard will look similar to this:

    clipboard.png.735088dedbbd194d954077315d0ba749.png

    The paste handler in the receiving application needs to be able to parse one of the provided formats. You'd think there's HTML in that list, so TinyMCE could simply paste that and all should be well - well, there's a caveat. Office tries to be nifty and conserve memory, so the HTML in the clipboard contains links to local files, which look like this in the source:

    <img width=224 height=237
    src="file:///C:/Users/Someone/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png"
    v:shapes="Grafik_x0020_1">

    Into the game come security zones and same origin policy, and so no, file:///somewhere isn't going to make it into your inline editor.

    Safari on MacOS is a different kind of beast. The pasted HTML contains the images inlined as blob URIs, something similar but not completely interchangeable with data URIs.

    There's a plugin for TinyMCE that promises to be able to paste the full HTML with the images and even call an upload handler with the image data. No idea if that one parses the RTF version of the clipboard instead or does some other magic.

    But, OTOH, I really wouldn't want my users to paste formatted content from office apps. Been there, seen the disaster, and never want to go back there. It never plays well with surrounding HTML, it tends produce awful glitches when scaling things and in the end, the frustration on the users' side always far outweighs the initial convenience.

    In case you're curious about the things available in your Windows system's clipboard, you can take a peek with InsideClipboard (that's how I took the screenshot above).

    • Like 4
  10. 34 minutes ago, artfulrobot said:

    you used ready not init. This makes sense; ready fires after all the installed modules have initialised, and we need ProcessWire to know that the InputfieldSelector module exists before adding a hook, presumably. (Note that your code worked for me using init() instead which I tested to see. I guess this is at risk of a race condition though; if my module loaded before InputfieldSelector did, it might not work).

    That shouldn't be a problem, actually. The WireHook class (someone correct me if I'm wrong) just builds a Selector and stores that in its hooks array. Every time a hookable method is called (through PHP's magic __call method), WireHook::runHooks is executed and checks wheter the any of the stored selectors match the currently called class and method and execute those. So it shouldn't matter when exactly you add the hook as long as PW's core has been loaded. For me, it's just a question of keeping the system startup lean why I perfer to add hooks in ready instead of init unless they have to be executed before ready() is triggered.

    38 minutes ago, artfulrobot said:

    You hooked InputfieldSelector not the parent Inputfield yours worked, mine didn't, so I guess we're not allowed to hook on parent classes?

    In theory, it shouldn't matter, but I haven't delved too deeply into the issue.

    • Like 1
  11. Can you try the following ready.php snippet (can't test it myself right now):

    <?php
    
    wire()->addHookAfter('FieldtypeRepeater::wakeupValue', function(HookEvent $event) {
    
      $field = $event->arguments('field');
      $page = $event->arguments('page');
      // The return value of wakeupValue is a RepeaterPageArray or subclass of it
      $repPageArray = $event->return;
      
      if($field->hasContext($page)) {
        $field = $field->getContext($page);
        $repPageArray->setField($field);
      }
      
    });

     

    • Like 1
  12. Did you set the autoload property in your module?

    I've assembled a snippet for site/ready.php that should add a checkbox to InputfieldSelector to allow system templates since the setting itself is already part of the inputfield code. Untested though since I'm in the middle of a big cleanup of my dev environment.

    wire()->addHookAfter('InputfieldSelector::getConfigInputfields', function (HookEvent $event) {
      
      $fields = $event->return;
      $inputfield = $event->object;
      
      $f = $event->modules->get('InputfieldCheckbox');
      $f->attr('id+name', 'allowSystemTemplates');
      $f->label = $event->_('Allow system templates');
      $f->setAttribute('checked', $inputfield->getSetting('allowSystemTemplates') ? 'checked' : '');
      $fields->append($f);
      
      $event->return = $fields;
      
    });

     

    • Like 1
  13. My personal believe is that ProcessWire would be the perfect platform for what you want to do, but you won't be able to completely circumvent a PHP learning curve. Since I don't know any platform or toolkit on the market that provides all the features you want without some programming (and the trend goes towards dropping pre-built solutions and requiring more programming, even with the "big players" like Sharepoint or Typo3), it's probably just a question of picking your poison.

    I'll try to answer your points as good as I can, though others with more experience with the specific requirement may have even better ideas.

    1. Member login is possible with the free FrontendUser module.
    2. Donations could e.g. be achieved with Stripe (Patreon, from what I hear, is cutting down on its APIs and trying to monetarize things to a point of pain). There's a stripe payment processor that's part of the commercial FormBuilder module.
    3. Taxonomy is an integral part of PW. Tagging, either with plain text tags or pages (the later even created on demand when you add a tag or relationship item) can easily be achieved out of the box, and there are free modules for things like creating two-way relationships between pages. PW's philosophy that "everything is a page" may sound a bit scary at first if you've worked with CMSes like WP or Drupal, but in the most simple case, a page is just a title field and auto-generated name living somewhere in the page tree.
    4. You actively have to implement (yourself or with a module) the blog behavior. If you want it, it's pretty simple with PW's built-in selectors and pagination.
    5. Really easy to implement. Add a "featured" checkbox to the templates that are relevant, call $pages->findOne('features=1, sort=-created') to your home template and render the returned page.
    6. This is easy too. Yes, it too requires small bits of PHP, but most of it is still CSS and JS. Just a small step up from a static HTML page.
    7. Again, FormBuilder might be a good choice here. There are a few more options out there as well, and you'll certainly get good responses here if you inquire with a specific example or use case.
    8. Rendering an RSS feed is possible (though I haven't used those in a long time) with free modules, it just needs a tiny bit of (well documented) programming.
    9. Just add PW's core Markdown Textformatter or (if you want to mix Markdown and HTML) install and add TextformatterMarkdownInMarkup in the field's configuration, and it will convert the markdown when the contents are shown in the frontend.

    One thing I'd like to add: you'll certainly not find a CMS with a more friendly and helpful community than PW.

    • Like 9
×
×
  • Create New...