Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ajax Files Upload #748

Merged
merged 31 commits into from
Aug 29, 2016
Merged

Ajax Files Upload #748

merged 31 commits into from
Aug 29, 2016

Conversation

w00fz
Copy link
Member

@w00fz w00fz commented Aug 24, 2016

This is a work in progress, mostly working, rework of the file field.

What Changes and How It Works

The file field is now decoupled from the Save task and doesn't rely anymore on the native file type. Instead, files drag and dropped into a field are now automatically uploaded, validated and held in a queue until the Save task kicks in. Same goes for removal of files, they are now Ajaxified, allowing the page to not be reloaded.

This implementation speeds up tremendously how the Save work, because now there is no longer the need of waiting for all the file to finish uploading, before the Save tasks can continue.

Because the uploaded files are held in a session queue until Save, if the user refreshes or leaves the current page, all uploaded files will be discarded.

Files settings and stored values are fully backward compatible, in addition there are a couple new options and enhancements.

New Options

limit

multiple: true
limit: 10 # 0 = unlimited

A great addition that wouldn't be possible with the native file type implementation is limit. It allows to constrain the number of allowed files for an individual field. If multiple: true is not enabled (which it isn't by default), limit automatically falls back to 1.

filesize

filesize: 5 # in MB, 0 = unlimited (constraint to `system.media.upload_limit` setting)

Another addition that the native file type implementation doesn't permit is filesize. This setting allows to constrain the maximum size (in MB) for a file and for each individual field.

Enhanced

accept

accept:
  - image/*

In addition to the MIME type, accept now alow allows extensions. For example, to only allow yaml and json files:

accept:
  - .yaml
  - .json

It is also now possible to allow any file by simply using the * (star) notation: accept: [‘*’].

destination

destination: 'user/plugins/testing`

Destination has been enhanced to allow self@ as well as page@: and theme@: prefixes.
Example of usage, assuming we have a blog item at the route /blog/ajax-upload (physical location being user/pages/02.blog/ajax-upload), with the page@: prefix the destination would be:

destination: 'page@:/blog/ajax-upload'

NOTE: self@ is not allowed outside of the Pages scope, an error will be thrown.

What's Missing

  • Missing logic in onPagesInitialized to clear out orphan files from the tmp:// location.
  • BlueprintSchema is not capable of handling nested fields right now (@mahagr).
  • random_name and avoid_overwriting settings are not documented. This will be added in the file field docs as they need updating anyway
  • On Save and in single file mode, there is currently no logic to delete the previously stored file, leaving it as orphan. No longer needed since a file needs to be removed before you can upload a new one
  • Many error strings need to be made translatable
  • This same implementation needs to be applied in the form plugin as well.
  • When removing a file, the JSON needs to be updated via JS
  • Selecting a file (by clicking the droppable area) is not bringing up Dropzone but native file.
  • Files in list need to get initialized when a new list item is added (DOM Nodes changes)

w00fz added 13 commits August 23, 2016 16:33
…ored upon Save

This improves the Save task tremendously as now there is no longer the need of waiting for the files to finish uploading. Fully backward compatible, `file` field now includes also a `limit` and `filesize` option in the blueprints. The former determines how many files are allowed to be uploaded when in combination with `multiple: true` (default: 10), the latter determines the file size limit (in MB) allowed for each file (default: 5MB)
…es that haven’t been saved yet, from the flash object session
# Conflicts:
#	themes/grav/css-compiled/template.css
#	themes/grav/css-compiled/template.css.map
@w00fz
Copy link
Member Author

w00fz commented Aug 26, 2016

random_name and avoid_overwriting have been tested and work fine, they still need documentation.

w00fz and others added 16 commits August 25, 2016 19:20
# Conflicts:
#	CHANGELOG.md
#	themes/grav/css-compiled/preset.css
#	themes/grav/css-compiled/preset.css.map
#	themes/grav/css-compiled/template.css
#	themes/grav/css-compiled/template.css.map
#	themes/grav/js/admin.min.js
#	themes/grav/js/vendor.min.js
# Conflicts:
#	CHANGELOG.md
#	themes/grav/js/admin.min.js
#	themes/grav/templates/partials/base.html.twig
# Conflicts:
#	themes/grav/js/admin.min.js
@flaviocopes
Copy link
Contributor

Tested, all looks good to me!

@w00fz w00fz merged commit 6b34336 into develop Aug 29, 2016
@w00fz w00fz changed the title [WIP] Ajax Files Upload Ajax Files Upload Aug 30, 2016
@metadiv
Copy link

metadiv commented Sep 21, 2016

Im having some problems using this in the front end.

BluePrint:

header.logo:
    type: File
    destination: '@self'
    multiple: false
    accept:
        - image/*
    label: Select Project logo (256px X 390px)

Output to MD:

logo:
    user/pages/01.demo-client/01.project-001/project-logo.png:
        name: project-logo.png
        type: image/png
        size: 7724
        path: user/pages/01.demo-client/01.project-001/project-logo.png

Things I have tried in TWig

{{page.header.logo}}   {# Returns Array String error #}
{{page.header.logo.path}}   {# Nothing returned #}
{{page.header.logo.0.path}}   {# Nothing returned #}
{{ page.media[page.header.logo].url }}   {# Returns Array String error #}
{{ page.media[page.header.logo.path].url }}   {# Nothing returned #}
{{ page.media[page.header.logo.0.path].url }}   {# Nothing returned #}

Can you explain how I can actually use an image uploaded with this method in my front end please?

@w00fz
Copy link
Member Author

w00fz commented Sep 21, 2016

Hi @metadiv, this would have been probably best opened as a new issue for question.

You can access your values via:

{% for filePath, fileData in  page.header.logo %}
    <img src="{{ filePath }}" alt="{{ fileData.name }}" />
{% endfor %}

@metadiv
Copy link

metadiv commented Sep 22, 2016

Thank you for the reply @w00fz , Can I suggest that someone adds this to the grav docs (I couldn't find it but if its there my apologies)

I also discovered you can use the page.media[] and the .name.
{% for logo in page.header.logo %}{{page.media[logo.name].url}}{% endfor %}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants