使用CSS媒体查询和Flask / Jinja进行设备检测(Device Detection Using CSS Media Queries and Flask/Jinja)

编程入门 行业动态 更新时间:2024-10-28 03:26:17
使用CSS媒体查询和Flask / Jinja进行设备检测(Device Detection Using CSS Media Queries and Flask/Jinja)

我正在尝试使用Jinja和Flask的CSS媒体查询来确定设备类型并根据设备提供适当大小的图像。 来自手机的请求将获得比台式机,平板电脑等更小的图像。

问题是{{ post|get_image(post, 480) }}独立于媒体查询进行评估,从而触发每个实例的get_image自定义模板过滤器。 get_image也是为设备呈现正确图像的位置,因此多次(可能是不必要的)调用会对性能产生负面影响。

理想情况下,只有一个媒体查询通过一次调用get_image来制定,但挑战在于媒体查询和Jinja完全相互独立,因为一个人对另一个一无所知。

我真的很感激其他方法或建议来改进我的方法。 提前致谢!

以下是媒体查询的示例:

@media only screen and (max-device-width: 480px) { .post { background: url("{{ post|get_image(post, 480) }}") no-repeat center center fixed; } } @media only screen and (max-device-width: 1224px) { .post { background: url("{{ post|get_image(post, 1224) }}") no-repeat center center fixed; } }

I'm trying to use CSS media queries with Jinja and Flask to determine device type and serve appropriately sized images based on the device. Requests from mobile phones would get smaller images than desktops, tablets, etc.

The problem is that {{ post|get_image(post, 480) }} gets evaluated independent of the media query thus triggering the get_image custom template filter for each instance. get_image is also where the correct image is rendered for the device, so multiple, perhaps unnecessary, calls can negatively effect performance.

Ideally, only one media query is enacted with one call to get_image, but the challenge is that the media query and Jinja are completely independent of each other in that one knows nothing about the other.

I'd really appreciate alternative approaches or suggestions to improve my approach. Thanks in advance!

Here's an example of the media queries:

@media only screen and (max-device-width: 480px) { .post { background: url("{{ post|get_image(post, 480) }}") no-repeat center center fixed; } } @media only screen and (max-device-width: 1224px) { .post { background: url("{{ post|get_image(post, 1224) }}") no-repeat center center fixed; } }

最满意答案

将您的设置更改为以下内容:

.post { background: none no-repeat center center fixed; } @media only screen and (max-device-width: 480px) { .post { background-image: url("{{ get_image_url(post, 480) }}"); } } @media only screen and (max-device-width: 1224px) { .post { background-image: url("{{ get_image_url(post, 1224) }}"); } }

您生成的URL可能如下所示:

/posts/<int:post_id>/background?s=NNNN

然后,设置代理服务器以从缓存目录中提供此类映像,并在映像不存在时将其转发到映像生成控制器:

# Fake server configuration # for no server known to man location /posts/(:post-id:\d+)/background { try_files /cache/:post-id:_\d+\.png or @flask-server }

最后,在Flask控制器中生成映像,将其保存到缓存目录,然后将其提供给请求者:

@app.route("/posts/<int:post_id>/background") def generate_image(post_id): # Assume that if we got here the image does not yet exist dimensions = int(request.args.get("s", 800), 10) image_data = generate_image(post_id, dimensions) image_name = "{}_{}.png".format(post_id, dimensions) image_path = os.path.join("/cache", image_name) with open(image_path, "wb") as image: image.write(image_data) return Response(image_data, content_type="image/png")

如果图像生成部分太昂贵甚至无法考虑在控制器中进行操作,则可以返回204 No-Content,其中Cache-Control设置为private并且过去设置为Expires并将图像生成任务放入进程外队列。 然后,只需在JavaScript代码中轮询该端点,直到映像准备好由代理服务器提供服务。

Change your setup to be something like this:

.post { background: none no-repeat center center fixed; } @media only screen and (max-device-width: 480px) { .post { background-image: url("{{ get_image_url(post, 480) }}"); } } @media only screen and (max-device-width: 1224px) { .post { background-image: url("{{ get_image_url(post, 1224) }}"); } }

The URLs you are generating might look something like this:

/posts/<int:post_id>/background?s=NNNN

Then, set up your proxy server to serve such images out of a cache directory and to forward them on to your image generation controller if the image does not exist:

# Fake server configuration # for no server known to man location /posts/(:post-id:\d+)/background { try_files /cache/:post-id:_\d+\.png or @flask-server }

Finally, in your Flask controller generate the image, save it to your cache directory, and serve it back to the requester:

@app.route("/posts/<int:post_id>/background") def generate_image(post_id): # Assume that if we got here the image does not yet exist dimensions = int(request.args.get("s", 800), 10) image_data = generate_image(post_id, dimensions) image_name = "{}_{}.png".format(post_id, dimensions) image_path = os.path.join("/cache", image_name) with open(image_path, "wb") as image: image.write(image_data) return Response(image_data, content_type="image/png")

If the image generation part is too expensive to even contemplate doing in the controller you can instead return 204 No-Content with Cache-Control set to private and Expires set in the past and put the image generation task into an out-of-process queue. Then just poll that endpoint in your JavaScript code until the image is ready to be served by your proxy server.

更多推荐

本文发布于:2023-08-07 22:20:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1466469.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:媒体   设备   Jinja   Flask   CSS

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!