Package: django-wools
Django WoolsDjango tools from WITH.That's a collection of things that we atWITHgot
tired of copy/pasting in every project.Installpip install django_woolsIncluded WoolsStoragedjango_wools.storage.GzipManifestStaticFilesStorageThat's a sub-class of theManifestStaticFilesStoragebut that makes sure that along with all the files comes a.gzversion which
is easy to pick up for nginx (or other static files server).Middlewaresdjango_wools.middlewares.NowMiddlewareSuppose that you have a content that is available up until a given date. When
the date is passed then everything related to this content expires. However,
in order to do this, you're probably going to make several request, possibly in
loosely connected parts of your code. In those cases, when looking at the time,
the clock will show different value as the time passes between calls. It means
that you could very well end up with one half of your code considering that the
object is still valid but the other half that it expired.In order to prevent this, the simplest is to consider that the time is fixed
and that the code executes instantly at the moment of the request. The goal
of this middleware is to save the current time at each request and then to
provide an easy way to get the current time through the request.If the middleware is activated, you should be able to get the time like this:fromtimeimportsleepfromdjango.shortcutsimportrenderdefmy_view(request):print(f"Now is{request.now()}")sleep(42)print(f"Now is still{request.now()}")returnrender(request,"something.html",{"now":request.now()})django_wools.middlewares.SlowMiddlewareWhen developing a SPA or hybrid app, you want to make sure that the app is
structurally ready to handle load times from the server, even if the connection
is a bit shaky. Also, you want to make sure that not too many requests are
sent.In order for you to fully realize how slow your website is going to be on a bad
connection, th e SlowMiddleware will automatically add a delay before replying
to each request.Add this to yoursettings.pyMIDDLEWARE=[# ..."django_wools.middlewares.SlowMiddleware",]SLOW_MIDDLEWARE_LATENCY=1ifDEBUGelse0By doing this, your requests will be added a 1s delay if theDEBUGmode is
enabled.Databasedjango_wools.db.require_lockProvides a way to explicitly generate a PostgreSQL lock on a table.By example:fromdjango.db.transactionimportatomicfromdjango_wools.dbimportrequire_lockfrommy_app.modelsimportMyModel@atomic@require_lock(MyModel,'ACCESS EXCLUSIVE')defmyview(request):# do stuff hereWagtail ImagesSeveral Wagtail-specific tags are provided to deal with images and more
specifically responsive images. To use it:Adddjango_woolstoINSTALLED_APPSImportwools_for_wt_imagesfrom your template{% load wools_for_wt_images %}Some specific settings can be set:WOOLS_MAX_PIXEL_RATIO(default:3)— Highest device pixel ratio
to support.WOOLS_INCREMENT_STEP_PERCENT(default:(sqrt(2) - 1) * 100)— The
percentage of increase from the base density to the next one. The default
values will generatex1,x2andx4with intermediate values that arex1.4142andx2.8284.All the tags will be default generate WebP images with a PNG fallback. The
fallback can be changed to JPEG and the main format has to be WebP.image_fixed_sizeThis tag will generate a<picture>tag for an image whose size in pixels you
known in advance. That picture size will be enforced in the HTML code with
inline properties.Usage:{% image_fixed_size max-500x500 %}The arguments to this tag, in order, are:image— The Wagtail-compatible image itselfspec— A spec like you would give to Wagtail (fill-500x500,max-500x500, etc)css_class— CSS class that will be added to the root  element.fallback_format— The format to fallback in case the browser doesn't
support WebP. Can either be"jpeg"or"png". Defaults to"png".lossless— A boolean to enable losslessness of WebP. This does not
affect the fallback format, so if you want a lossless fallback as well you'll
need to use PNG.FontsWools offers a way to easily download and manage fonts from Google fonts or
other pluggable providers. The current version only works with Google fonts,
however you are free to create your own sources and converters that will be
able to work out what you need.Getting startedThe first thing would be to put the font families that you want into thesettings.pyof your project. By example:WOOLS_FONTS_FAMILIES=[('google','Roboto'),('google','Nunito'),]Here we're getting Roboto and Nunito from Google Fonts.Note— Please make sure thatdjango_woolsis in yourINSTALLED_APPSfor this to work.Now let's run the download command:./manage.py wools_import_fontsAnd finally, let's put this tag in your page's HTML:{% load wools_fonts %}<!DOCTYPE html><htmlclass="no-js"lang="{{ CURRENT_LANG }}"><head><metacharset="utf-8"/><metaname="viewport"content="width=device-width, initial-scale=1"/><title>{{ title }}</title>{% fonts_head %}</head></html>And that's it! The fonts you asked for will be loaded automatically.Configuration optionsThere is several settings that you can adjust.WOOLS_FONTS_DIRDirectory name relative to the static root where the files will be stored.Default:"fonts"WOOLS_STATIC_ROOTAbsolute path to the static root that you want to use to store the fonts. If
set to none, the first value fromSTATICFILES_DIRSwill be used instead.Default:NoneWOOLS_FAMILIESFont families that you want to load. It's a list of (provider, family) tuples.Instead of providing tuples, you can providedjango_wools.settings_types.FontFamilyinstances directly. In case you don't
provide them, the tuple will be passed as *args to the constructor ofFontFamily.Default:[]WOOLS_FONTS_PROVIDERSDictionary of available font providers. The key is the name of the provider
while the value is the FQN of the class.If you want to provide your own provider, you can specifcy any class as long as
it implements thedjango_wools.fonts.WoolFontProviderinterface.Default:{"google": "django_wools.fonts.GoogleFontsProvider"}WOOLS_FONTS_FORMATSList of font formats that you want. Choices arettf,woff,woff2,eot,svg,otf. You can also directly provide instances ofdjango_wools.settings_types.FontFormat.Font formats will be proposed in the same order to the browser.Default:[FontFormat.woff2, FontFormat.ttf]WOOLS_FONTS_CONVERSIONSFont sources will provide the fonts in a given format (most likely TTF) but in
order to produce the formats expected byWOOLS_FONTS_FORMATSyou need to
convert those fonts.This is a dictionary that as key takes a tuple of (from_format, to_format) and
as value a sequential list of converters to use.By example, suppose that you only have "TTF to WOFF2" and "EOT to TTF" avaible
and your source is in EOT while formats are TTF and WOFF2. In that case you can
specificy that the conversion from "EOT to WOFF2" goes through TTF.Default:{(FontFormat.ttf,FontFormat.woff):["django_wools.fonts.TtfToWoff"],(FontFormat.ttf,FontFormat.woff2):["django_wools.fonts.TtfToWoff2"],}