def render(self, context, instance, placeholder): context = self.super(TextImagePlugin, self).render(context, instance, placeholder) try: aspect_ratio = compute_aspect_ratio(instance.image) except Exception: # if accessing the image file fails, abort here return context resize_options = instance.glossary.get('resize_options', {}) crop = 'crop' in resize_options upscale = 'upscale' in resize_options subject_location = instance.image.subject_location if 'subject_location' in resize_options else False high_resolution = 'high_resolution' in resize_options image_width = instance.glossary.get('image_width', '') if not image_width.endswith('px'): return context image_width = int(image_width.rstrip('px')) image_height = instance.glossary.get('image_height', '') if image_height.endswith('px'): image_height = int(image_height.rstrip('px')) else: image_height = int(round(image_width * aspect_ratio)) context['src'] = { 'size': (image_width, image_height), 'size2x': (image_width * 2, image_height * 2), 'crop': crop, 'upscale': upscale, 'subject_location': subject_location, 'high_resolution': high_resolution, } link_attributes = LinkPluginBase.get_html_tag_attributes(instance) context['link_html_tag_attributes'] = format_html_join(' ', '{0}="{1}"', [(attr, val) for attr, val in link_attributes.items() if val] ) return context
def render(self, context, instance, placeholder): try: aspect_ratio = compute_aspect_ratio(instance.image) except Exception: # if accessing the image file fails, abort here return context resize_options = instance.glossary.get('resize_options', {}) crop = 'crop' in resize_options upscale = 'upscale' in resize_options subject_location = instance.image.subject_location if 'subject_location' in resize_options else False high_resolution = 'high_resolution' in resize_options image_width = instance.glossary.get('image_width', '') if not image_width.endswith('px'): return context image_width = int(image_width.rstrip('px')) image_height = instance.glossary.get('image_height', '') if image_height.endswith('px'): image_height = int(image_height.rstrip('px')) else: image_height = int(round(image_width * aspect_ratio)) src = { 'size': (image_width, image_height), 'size2x': (image_width * 2, image_height * 2), 'crop': crop, 'upscale': upscale, 'subject_location': subject_location, 'high_resolution': high_resolution, } context.update( dict(instance=instance, placeholder=placeholder, src=src)) return context
def render(self, context, instance, placeholder): try: aspect_ratio = compute_aspect_ratio(instance.image) except Exception: # if accessing the image file fails, abort here return context resize_options = instance.glossary.get('resize_options', {}) crop = 'crop' in resize_options upscale = 'upscale' in resize_options subject_location = instance.image.subject_location if 'subject_location' in resize_options else False high_resolution = 'high_resolution' in resize_options image_width = instance.glossary.get('image_width', '') if not image_width.endswith('px'): return context image_width = int(image_width.rstrip('px')) image_height = instance.glossary.get('image_height', '') if image_height.endswith('px'): image_height = int(image_height.rstrip('px')) else: image_height = int(round(image_width * aspect_ratio)) src = { 'size': (image_width, image_height), 'size2x': (image_width * 2, image_height * 2), 'crop': crop, 'upscale': upscale, 'subject_location': subject_location, 'high_resolution': high_resolution, } context.update(dict(instance=instance, placeholder=placeholder, src=src)) return context
def render(self, context, instance, placeholder): marker_instances = [] for inline_element in instance.inline_elements.all(): try: ProxyModel = create_proxy_model( 'LeafletMarker', (ImagePropertyMixin, MarkerModelMixin), InlineCascadeElement, module=__name__) marker = ProxyModel(id=inline_element.id, glossary=inline_element.glossary) try: aspect_ratio = compute_aspect_ratio(marker.image) width = parse_responsive_length( marker.glossary.get('marker_width') or '25px') marker.size = list( get_image_size(width[0], (None, None), aspect_ratio)) marker.size2x = 2 * marker.size[0], 2 * marker.size[1] except Exception: # if accessing the image file fails, skip size computations pass else: try: marker_anchor = marker.glossary['marker_anchor'] top = parse_responsive_length(marker_anchor['top']) left = parse_responsive_length(marker_anchor['left']) if top[0] is None or left[0] is None: left = width[0] * left[1] top = width[0] * aspect_ratio * top[1] else: left, top = left[0], top[0] marker.anchor = [left, top] except Exception: pass marker_instances.append(marker) except (KeyError, AttributeError): pass context.update( dict(instance=instance, placeholder=placeholder, settings=self.settings, config=app_settings.CMSPLUGIN_CASCADE['leaflet'], markers=marker_instances)) return context
def render(self, context, instance, placeholder): marker_instances = [] for inline_element in instance.inline_elements.all(): try: ProxyModel = create_proxy_model('LeafletMarker', (ImagePropertyMixin, MarkerModelMixin), InlineCascadeElement, module=__name__) marker = ProxyModel(id=inline_element.id, glossary=inline_element.glossary) try: aspect_ratio = compute_aspect_ratio(marker.image) width = parse_responsive_length(marker.glossary.get('marker_width') or '25px') marker.size = list(get_image_size(width[0], (None, None), aspect_ratio)) marker.size2x = 2 * marker.size[0], 2 * marker.size[1] except Exception: # if accessing the image file fails, skip size computations pass else: try: marker_anchor = marker.glossary['marker_anchor'] top = parse_responsive_length(marker_anchor['top']) left = parse_responsive_length(marker_anchor['left']) if top[0] is None or left[0] is None: left = width[0] * left[1] top = width[0] * aspect_ratio * top[1] else: left, top = left[0], top[0] marker.anchor = [left, top] except Exception: pass marker_instances.append(marker) except (KeyError, AttributeError): pass context.update(dict(instance=instance, placeholder=placeholder, settings=self.settings, config=app_settings.CMSPLUGIN_CASCADE['leaflet'], markers=marker_instances)) return context
def get_image_tags(instance): """ Create a context returning the tags to render an <img ...> element with ``sizes``, ``srcset``, a fallback ``src`` and if required inline styles. """ if hasattr(instance, 'image') and hasattr(instance.image, 'exif'): aspect_ratio = compute_aspect_ratio(instance.image) elif 'image' in instance.glossary and 'width' in instance.glossary['image']: aspect_ratio = compute_aspect_ratio_with_glossary(instance.glossary) instance.glossary['ramdom_svg_color'] = 'hsl({}, 30%, 80%, 0.8)'.format( str(random.randint(0, 360))) else: # if accessing the image file fails or fake image fails, abort here logger.warning("Unable to compute aspect ratio of image '{}'".format(instance.image)) return is_responsive = 'img-fluid' in instance.glossary.get('image_shapes', []) resize_options = instance.glossary.get('resize_options', {}) crop = 'crop' in resize_options upscale = 'upscale' in resize_options if 'subject_location' in resize_options and hasattr(instance.image, 'subject_location'): subject_location = instance.image.subject_location else: subject_location = None tags = {'sizes': [], 'srcsets': {}, 'is_responsive': is_responsive, 'extra_styles': {}} if is_responsive: image_width = parse_responsive_length(instance.glossary.get('image_width_responsive') or '100%') assert(image_width[1]), "The given image has no valid width" if image_width[1] != 1.0: tags['extra_styles'].update({'max-width': '{:.0f}%'.format(100 * image_width[1])}) else: image_width = parse_responsive_length(instance.glossary['image_width_fixed']) if not image_width[0]: image_width = (instance.image.width, image_width[1]) try: image_height = parse_responsive_length(instance.glossary['image_height']) except KeyError: image_height = (None, None) if is_responsive: column_bounds_min = instance.glossary['column_bounds']['min'] if 'high_resolution' in resize_options: column_bounds_max = 2 * instance.glossary['column_bounds']['max'] else: column_bounds_max = instance.glossary['column_bounds']['max'] num_steps = min(int((column_bounds_max - column_bounds_min) / app_settings.RESPONSIVE_IMAGE_STEP_SIZE), app_settings.RESPONSIVE_IMAGE_MAX_STEPS) step_width, max_width = (column_bounds_max - column_bounds_min) / num_steps, 0 for step in range(0, num_steps + 1): width = round(column_bounds_min + step_width * step) max_width = max(max_width, width) size = get_image_size(width, image_height, aspect_ratio) key = '{0}w'.format(*size) tags['srcsets'][key] = {'size': size, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} tags['sizes'] = instance.glossary['media_queries'].values() # use an existing image as fallback for the <img ...> element if not max_width > 0: logger.warning('image tags: image max width is zero') size = (int(round(max_width)), int(round(max_width * aspect_ratio))) else: size = get_image_size(image_width[0], image_height, aspect_ratio) if 'high_resolution' in resize_options: tags['srcsets']['1x'] = {'size': size, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} tags['srcsets']['2x'] = dict(tags['srcsets']['1x'], size=(size[0] * 2, size[1] * 2)) tags['src'] = {'size': size, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} return tags
def get_image_tags(context, instance, options): """ Create a context returning the tags to render an <img ...> element: ``sizes``, ``srcset``, a fallback ``src`` and if required inline styles. """ if hasattr(instance, 'image') and hasattr(instance.image, 'exif'): aspect_ratio = compute_aspect_ratio(instance.image) elif 'image' in instance.glossary and 'width' in instance.glossary['image']: aspect_ratio = compute_aspect_ratio_with_glossary(instance.glossary) instance.glossary['ramdom_svg_color'] = 'hsl({}, 30%, 80%, 0.8)'.format( str(random.randint(0, 360))) else: # if accessing the image file fails or fake image fails, abort here logger.warning("Unable to compute aspect ratio of image '{}'".format(instance.image)) return is_responsive = options.get('is_responsive', False) resize_options = options.get('resize_options', {}) crop = 'crop' in resize_options upscale = 'upscale' in resize_options if hasattr(instance.image, 'subject_location'): subject_location = instance.image.subject_location and 'subject_location' in resize_options else: subject_location = None resolutions = (False, True) if 'high_resolution' in resize_options else (False,) tags = {'sizes': [], 'srcsets': {}, 'is_responsive': is_responsive, 'extra_styles': {}} if is_responsive: image_width = parse_responsive_length(options.get('image_width_responsive') or '100%') assert(image_width[1]), "The given image has no valid width" if image_width[1] != 1.0: tags['extra_styles'].update({'max-width': '{:.0f}%'.format(100 * image_width[1])}) else: image_width = parse_responsive_length(options['image_width_fixed']) if not image_width[0]: image_width = (instance.image.width, image_width[1]) try: image_height = parse_responsive_length(options['image_height']) except KeyError: image_height = (None, None) set_defaults(options) if is_responsive: max_width = 0 for bp in options['breakpoints']: if bp not in options['container_max_widths']: continue width = int(image_width[1] * options['container_max_widths'][bp]) max_width = max(max_width, width) size = get_image_size(width, image_height, aspect_ratio) if bp in options['media_queries']: tags['sizes'].append('{0} {1}px'.format(' and '.join(options['media_queries'][bp]), width)) for high_res in resolutions: if high_res: size = (size[0] * 2, size[1] * 2) key = '{0}w'.format(size[0]) tags['srcsets'][key] = {'size': size, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} # use an existing image as fallback for the <img ...> element if not max_width > 0: logger.warning('image tags: image max width is zero') size = (int(round(max_width)), int(round(max_width * aspect_ratio))) else: size = get_image_size(image_width[0], image_height, aspect_ratio) if len(resolutions) > 1: for high_res in resolutions: if high_res: tags['srcsets']['2x'] = {'size': (size[0] * 2, size[1] * 2), 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} else: tags['srcsets']['1x'] = {'size': size, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} tags['src'] = {'size': size, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location} return tags
def get_picture_elements(context, instance): """ Create a context, used to render a <picture> together with all its ``<source>`` elements: It returns a list of HTML elements, each containing the information to render a ``<source>`` element. The purpose of this HTML entity is to display images with art directions. For normal images use the ``<img>`` element. """ if hasattr(instance, 'image') and hasattr(instance.image, 'exif'): aspect_ratio = compute_aspect_ratio(instance.image) elif 'image' in instance.glossary and 'width' in instance.glossary['image']: aspect_ratio = compute_aspect_ratio_with_glossary(instance.glossary) instance.glossary['ramdom_svg_color'] = 'hsl({}, 30%, 80%, 0.8)'.format( str(random.randint(0, 360))) else: # if accessing the image file fails or fake image fails, abort here logger.warning("Unable to compute aspect ratio of image '{}'".format(instance.image)) return complete_glossary = instance.get_complete_glossary() container_max_heights = complete_glossary.get('container_max_heights', {}) resize_options = instance.glossary.get('resize_options', {}) crop = 'crop' in resize_options upscale = 'upscale' in resize_options if hasattr(instance.image, 'subject_location'): subject_location = instance.image.subject_location and 'subject_location' in resize_options else: subject_location = None max_width = 0 max_zoom = 0 elements = [] for bp in complete_glossary['breakpoints']: try: width = float(complete_glossary['container_max_widths'][bp]) except KeyError: width = 0 max_width = max(max_width, round(width)) size = None try: image_height = parse_responsive_length(instance.glossary['responsive_heights'][bp]) except KeyError: image_height = (None, None) if image_height[0]: # height was given in px size = (int(width), image_height[0]) elif image_height[1]: # height was given in % size = (int(width), int(round(width * aspect_ratio * image_height[1]))) elif bp in container_max_heights: container_height = parse_responsive_length(container_max_heights[bp]) if container_height[0]: size = (int(width), container_height[0]) elif container_height[1]: size = (int(width), int(round(width * aspect_ratio * container_height[1]))) try: zoom = int( instance.glossary['responsive_zoom'][bp].strip().rstrip('%') ) except (AttributeError, KeyError, ValueError): zoom = 0 max_zoom = max(max_zoom, zoom) if size is None: # as fallback, adopt height to current width size = (int(width), int(round(width * aspect_ratio))) try: media_queries = complete_glossary['media_queries'][bp][:] except KeyError: media_queries = [] media = ' and '.join(media_queries) elem = {'tag': 'source', 'size': size, 'zoom': zoom, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location, 'media': media} if 'high_resolution' in resize_options: elem['size2'] = (size[0] * 2, size[1] * 2) elements.append(elem) # add a fallback image for old browsers which can't handle the <picture> element if image_height[1]: size = (int(max_width), int(round(max_width * aspect_ratio * image_height[1]))) else: size = (int(max_width), int(round(max_width * aspect_ratio))) elements.append({'tag': 'img', 'size': size, 'zoom': max_zoom, 'crop': crop, 'upscale': upscale, 'subject_location': subject_location}) return elements