def theme_rename(request, form_class=ThemeNameForm): if not request.user.profile.is_superuser: raise Http403 selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 theme_root = get_theme_root(selected_theme) form = form_class(request.POST or None) ret_dict = {'success': False, 'err': ''} if form.is_valid(): new_theme_name = form.cleaned_data['theme_name'] if is_valid_theme(new_theme_name): ret_dict['err'] = _('Theme "%(name)s" already exists' % {'name': new_theme_name}) return HttpResponse(json.dumps(ret_dict)) if not is_valid_path(settings.ORIGINAL_THEMES_DIR, new_theme_name): raise Http403 new_theme_root = get_theme_root(new_theme_name) shutil.move(theme_root, new_theme_root) ret_dict['success'] = True EventLog.objects.log() #else: # ret_dict['err'] = form.errors.as_json() return HttpResponse(json.dumps(ret_dict))
def remove_google_profile_from_page_view(apps, schema_editor): """ Remove the google_profile block from pages/view.html {% if page.google_profile %} {% if page.has_google_author %} <a href="{{ page.google_profile }}?rel=author">{% trans "View Author's Google+ Profile" %}</a> {% elif page.has_google_publisher %} <a href="{{ page.google_profile }}" rel="publisher">{% trans "View Publisher's Google+ Page" %}</a> {% endif %} {% endif %} """ import re import os from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() file_path = '{}/templates/pages/view.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() p = r'{0}([\d\D\s\S\w\W]*?){1}([\s\S]*?){2}'.format( re.escape('{% if page.google_profile %}'), re.escape('{% endif %}'), re.escape('{% endif %}')) content = re.sub(p, '', content) with open(file_path, 'w') as f: f.write(content)
def __init__(self, theme): self.orig_name = theme self.name = theme self.description = u'' self.tags = u'' self.screenshot = u'' self.screenshot_thumbnail = u'' self.author = u'' self.author_uri = u'' self.version = u'' self.create_dt = datetime.now() theme_root = get_theme_root(theme) # check if theme info file exists is_file = qstr_is_file(DEFAULT_THEME_INFO, ROOT_DIR=theme_root) if is_file: theme_file = file(os.path.join(theme_root, DEFAULT_THEME_INFO)) data = theme_file.readlines() theme_file.close() # set attributes according to data in info file for datum in data: datum = datum.replace('\n', '') if "=" in datum: label, value = datum.split('=', 1) label = label.strip().replace(' ', '_').lower() value = value.strip() if label == 'create_dt': value = parse(value) if label in ('screenshot', 'screenshot_thumbnail'): value = os.path.join('/themes', theme, value) setattr(self, label, value)
def get_template_sources(self, template_name, template_dirs=None): """Return the absolute paths to "template_name", when appended to the selected theme directory in THEMES_DIR. Any paths that don't lie inside one of the template dirs are excluded from the result set, for security reasons. """ theme_templates = [] current_request = get_current_request() # this is needed when the theme is changed self.theme_root = get_theme_root() if current_request and current_request.mobile: theme_templates.append(os.path.join(self.theme_root, 'mobile')) theme_templates.append(os.path.join(self.theme_root, 'templates')) for template_path in theme_templates: try: if settings.USE_S3_THEME: yield os.path.join(template_path, template_name) else: yield safe_join(template_path, template_name) except SuspiciousFileOperation: # The joined path was located outside of this particular # template_dir (it might be inside another one, so this isn't # fatal). pass
def copy_file_to_theme(source_full_path, to_theme, path_to_file, filename): """Copies a file and all associated directories into theme """ root_dir = get_theme_root(to_theme) try: os.makedirs(os.path.join(root_dir, path_to_file)) except OSError: pass dest_full_path = os.path.join(root_dir, path_to_file, filename) shutil.copy(source_full_path, dest_full_path) # copy to s3 if settings.USE_S3_THEME: if os.path.splitext(filename)[1] == '.html': public = False else: public = True dest_path = os.path.join(to_theme, path_to_file, filename) dest_full_path = os.path.join(settings.THEME_S3_PATH, dest_path) save_file_to_s3(source_full_path, dest_path=dest_full_path, public=public) cache_key = ".".join([settings.SITE_CACHE_KEY, 'theme', dest_path]) cache.delete(cache_key) if hasattr(settings, 'REMOTE_DEPLOY_URL') and settings.REMOTE_DEPLOY_URL: urlopen(settings.REMOTE_DEPLOY_URL)
def remove_urlize_filter(apps, schema_editor): """ The urlize filter breaks the links in the description generated with wysiwyg editor. The issue has been fixed in core. This migration is to fix for the event template pulled down to the site. """ from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() file_path = f'{dir_path}/templates/events/view.html' if os.path.isfile(file_path): updated = False with open(file_path, 'r') as f: content = f.read() if content.find('|urlize') >= 0: content = content.replace( 'speaker.description|safe|urlize|linebreaks', 'speaker.description|safe|linebreaks') content = content.replace( 'organizer.description|safe|urlize|linebreaks', 'organizer.description|safe|linebreaks') content = content.replace('sponsor.description|safe|urlize', 'sponsor.description|safe') updated = True if updated: with open(file_path, 'w') as f: f.write(content)
def render_to_theme(request, template_name, context={}, **kwargs): """Loads the given template_name and renders it with the given context. The template_name may be a string to load a single template using get_template, or it may be a tuple to use select_template to find one of the templates in the list. Returns a string. This shorcut prepends the template_name given with the selected theme's directory """ context['CUSTOM_THEME'] = False context['THEME_TEMPLATE'] = template_name if 'disable_theme' in request.GET: if isinstance(template_name, (list, tuple)): t = select_default_template(template_name) else: t = get_default_template(template_name) else: if isinstance(template_name, (list, tuple)): t = select_template(template_name) else: t = get_template(template_name) if t.origin and re.search(r'^%s.+' % get_theme_root(), t.origin.name): context['CUSTOM_THEME'] = True return strip_content_above_doctype( t.render(context=context, request=request))
def get_template_list(): """ Get a list of files from the template directory that begin with 'default-' """ file_list = [] theme_dir = get_theme_root() template_dir = os.path.join(theme_dir, 'templates') if os.path.isdir(template_dir): item_list = os.listdir(template_dir) else: item_list = [] for item in item_list: current_item = os.path.join(template_dir, item) path_split = os.path.splitext(current_item) extension = path_split[1] base_name = os.path.basename(path_split[0]) if os.path.isfile(current_item): if extension == ".html" and "default-" in base_name: base_display_name = base_name[8:].replace('-', ' ').title() file_list.append(( item, base_display_name, )) return sorted(file_list)
def remove_fb_like_from_custom_templates(apps, schema_editor): """ Remove facebook like buttons from custom templates (the templates pulled down to site). 1) pages/meta.html Remove facebook like block {% if show_fb_connect|default:False %} {% fb_like_button_iframe news.get_absolute_url height=20 %} {% endif %} """ import re import os from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() # pages/meta.html file_path = '{}/templates/pages/meta.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() p = r'{0}([\d\D\s\S\w\W]*?){1}'.format( re.escape('{% if show_fb_connect|default:False %}'), re.escape('{% endif %}')) content = re.sub(p, '', content) with open(file_path, 'w') as f: f.write(content)
def original_templates(request, template_name="theme_editor/original_templates.html"): selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 app = request.GET.get("app", None) current_dir = request.GET.get("dir", '') if current_dir: current_dir = current_dir.replace('\\', '/') current_dir = current_dir.strip('/') current_dir = current_dir.replace('////', '/') current_dir = current_dir.replace('///', '/') current_dir = current_dir.replace('//', '/') # if current_dir is a directory then append the # trailing slash so we can get the dirname below # get the previous directory name and path prev_dir = '/' prev_dir_name = 'original templates' current_dir_split = current_dir.split('/') if len(current_dir_split) > 1: prev_dir_name = current_dir_split[-2] current_dir_split.pop() prev_dir = '/'.join(current_dir_split) elif not current_dir_split[0]: prev_dir = '' if app in app_templates: root = app_templates[app] elif is_valid_theme(app): root = os.path.join(get_theme_root(app), 'templates') else: if '/' in app and app.split('/')[0] == 'builtin': builtin_base_name = app.split('/')[1] root = os.path.join(settings.TENDENCI_ROOT, "themes/{}/templates".format(builtin_base_name)) else: raise Http404(_('Specified theme or app does not exist')) if not is_valid_path(root, current_dir): raise Http403 dirs = get_dir_list(root, current_dir) files, non_editable_files = get_file_list(root, current_dir) return render_to_resp(request=request, template_name=template_name, context={ 'current_theme': selected_theme, 'app': app, 'current_dir': current_dir, 'prev_dir_name': prev_dir_name, 'prev_dir': prev_dir, 'dirs': dirs, 'files': files, 'non_editable_files': non_editable_files, })
def copy_to_theme(request): selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 app = request.GET.get("app", None) current_dir = request.GET.get("dir", '') if current_dir: current_dir = current_dir.replace('\\', '/') current_dir = current_dir.strip('/') current_dir = current_dir.replace('////', '/') current_dir = current_dir.replace('///', '/') current_dir = current_dir.replace('//', '/') chosen_file = request.GET.get("file", '') if chosen_file: chosen_file = chosen_file.replace('\\', '/') chosen_file = chosen_file.strip('/') chosen_file = chosen_file.replace('////', '/') chosen_file = chosen_file.replace('///', '/') chosen_file = chosen_file.replace('//', '/') if app in app_templates: root = app_templates[app] elif is_valid_theme(app): root = os.path.join(get_theme_root(app), 'templates') else: if '/' in app and app.split('/')[0] == 'builtin': builtin_base_name = app.split('/')[1] root = os.path.join( settings.TENDENCI_ROOT, "themes/{}/templates".format(builtin_base_name)) else: raise Http404(_('Specified theme or app does not exist')) if (not is_valid_path(root, current_dir) or not is_valid_path(root, os.path.join(current_dir, chosen_file))): raise Http403 full_filename = os.path.join(root, current_dir, chosen_file) if not os.path.isfile(full_filename): raise Http404 copy_file_to_theme(full_filename, selected_theme, os.path.join('templates', current_dir), chosen_file) msg_string = 'Successfully copied %s/%s to theme' % (current_dir, chosen_file) messages.add_message(request, messages.SUCCESS, _(msg_string)) EventLog.objects.log() return redirect('theme_editor.editor')
def __init__(self, *args, **kwargs): """ Hold the theme_root in self.theme_root instead of calling get_theme_root() in get_template_sources(). This significantly reduces the number of queries for get_setting('module', 'theme_editor', 'theme'). (reduced # of queries from 3316 to 233 when testing on my local for an article view. - @jennyq) """ self.theme_root = get_theme_root() super(Loader, self).__init__(engine)
def callback(file_path, uuid, selected_theme=selected_theme, file_dir=file_dir, overwrite=overwrite): theme_root = get_theme_root(selected_theme) file_name = os.path.basename(file_path) full_filename = os.path.join(file_dir, file_name) if (not is_valid_path(theme_root, file_dir) or not is_valid_path(theme_root, full_filename)): raise Http403 if os.path.isfile(os.path.join(theme_root, full_filename)) and not overwrite: msg_string = 'File %s already exists in that folder.' % (file_name) raise uploader.CallbackError(msg_string) copy_file_to_theme(file_path, selected_theme, file_dir, file_name) EventLog.objects.log()
def get_template_sources(self, template_name, template_dirs=None): """ Return possible absolute paths to "template_name" in the current theme and any themes it inherits from. Any paths that don't lie inside one of the template dirs are excluded from the result set for security reasons. """ request = get_current_request() mobile = (request and request.mobile) active_theme = get_active_theme() theme = get_theme(active_theme) cached_theme, theme_search_info = self.cached_theme_search_info # If the theme changed or the user is previewing a different theme, # recalculate theme_search_info. # Note that this Loader instance may be shared between multiple threads, # so you must be careful when reading/writing # self.cached_theme_search_info to ensure that writes in one thread # cannot cause unexpected behavior in another thread that is # reading/writing self.cached_theme_search_info at the same time. if cached_theme != theme: theme_search_info = [] for cur_theme in get_theme_search_order(theme): if is_builtin_theme(cur_theme) or not settings.USE_S3_THEME: theme_search_info.append( (cur_theme, get_theme_root(cur_theme), False)) else: theme_search_info.append((cur_theme, cur_theme, True)) if theme == active_theme: self.cached_theme_search_info = (theme, theme_search_info) for cur_theme, cur_theme_root, use_s3_theme in theme_search_info: for template_path in (['mobile', 'templates'] if mobile else ['templates']): if not use_s3_theme: try: template_file = safe_join(cur_theme_root, template_path, template_name) except SuspiciousFileOperation: # The joined path was located outside of template_path, # although it might be inside another one, so this isn't # fatal. continue else: template_file = os.path.join(cur_theme_root, template_path, template_name) origin = Origin(name=template_file, template_name=template_name, loader=self) origin.theme = cur_theme origin.use_s3_theme = use_s3_theme yield origin
def delete_file(request): selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 current_dir = request.GET.get("dir", '') if current_dir: current_dir = current_dir.replace('\\', '/') current_dir = current_dir.strip('/') current_dir = current_dir.replace('////', '/') current_dir = current_dir.replace('///', '/') current_dir = current_dir.replace('//', '/') if current_dir.startswith('plugins.'): current_dir = current_dir.split('plugins.')[1] chosen_file = request.GET.get("file", '') if chosen_file: chosen_file = chosen_file.replace('\\', '/') chosen_file = chosen_file.strip('/') chosen_file = chosen_file.replace('////', '/') chosen_file = chosen_file.replace('///', '/') chosen_file = chosen_file.replace('//', '/') theme_root = get_theme_root(selected_theme) if (not is_valid_path(theme_root, current_dir) or not is_valid_path( theme_root, os.path.join(current_dir, chosen_file))): raise Http403 full_filename = os.path.join(theme_root, current_dir, chosen_file) if not os.path.isfile(full_filename): raise Http404 os.remove(full_filename) if settings.USE_S3_STORAGE: s3_path = selected_theme + '/' + current_dir + chosen_file s3_full_path = settings.AWS_LOCATION + '/' + settings.THEME_S3_PATH + '/' + s3_path delete_file_from_s3(file=s3_full_path) cache_key = ".".join([settings.SITE_CACHE_KEY, 'theme', s3_path]) cache.delete(cache_key) msg_string = 'Successfully deleted %s/%s.' % (current_dir, chosen_file) messages.add_message(request, messages.SUCCESS, _(msg_string)) EventLog.objects.log() return redirect('theme_editor.editor')
def create_new_template(request, form_class=AddTemplateForm): """ Create a new blank template for a given template name """ selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 form = form_class(request.POST or None) ret_dict = {'created': False, 'err': ''} if form.is_valid(): template_name = form.cleaned_data['template_name'].strip() template_full_name = 'default-%s.html' % template_name existing_templates = [t[0] for t in get_template_list()] if template_full_name not in existing_templates: # create a new template and assign default content theme_root = get_theme_root(selected_theme) template_dir = os.path.join(theme_root, 'templates') template_full_path = os.path.join(template_dir, template_full_name) # grab the content from the new-default-template.html # first check if there is a customized one on the site default_template_name = 'new-default-template.html' default_template_path = os.path.join(template_dir, 'theme_editor', default_template_name) if not os.path.isfile(default_template_path): # no customized one found, use the default one default_template_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'templates/theme_editor', default_template_name) if os.path.isfile(default_template_path): default_content = open(default_template_path).read() else: default_content = '' with open(template_full_path, 'w') as f: f.write(default_content) if settings.USE_S3_STORAGE: s3_path = os.path.join(settings.THEME_S3_PATH, selected_theme, 'templates', template_full_name) save_file_to_s3(template_full_path, dest_path=s3_path, public=False) ret_dict['created'] = True ret_dict['template_name'] = template_full_name else: ret_dict['err'] = _('Template "%(name)s" already exists' % {'name': template_full_name}) return HttpResponse(json.dumps(ret_dict))
def get_default_template_choices(): newsletters_relative_path = 'newsletters/templates/default/' default_templates = [] for cur_theme in get_theme_search_order(): template_path = os.path.join(get_theme_root(cur_theme), 'templates', newsletters_relative_path) if os.path.isdir(template_path): default_templates += os.listdir(template_path) default_templates = list(set(default_templates)) default_templates.sort() template_choices = [] for template in default_templates: template_choices.append((newsletters_relative_path + template, os.path.splitext(template)[0])) return template_choices
def change_profile_photo_update_url(apps, schema_editor): """ Update two templates, top_menu/_profile_dropdown.html and profiles/index.html, that are pulled down to the site. Change the URL for profile photo update from gravatar.com to the upload url on the site as users now can upload profile photos. In the templates/top_menu/_profile_dropdown.html, update from //gravatar.com/ to {% url 'profile.upload_photo' user.id %} In the templates/profiles/index.html, update from //gravatar.com/ to {% url 'profile.upload_photo' user_this.id %}, and from "Create / update your gravatar" to "Change profile photo" """ from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() file_path = f'{dir_path}/templates/top_menu/_profile_dropdown.html' if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() content = content.replace( '//gravatar.com/', "{% url 'profile.upload_photo' user.id %}") with open(file_path, 'w') as f: f.write(content) file_path = f'{dir_path}/templates/profiles/index.html' if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() content = content.replace( 'https://en.gravatar.com', "{% url 'profile.upload_photo' user.id %}") content = content.replace( '//gravatar.com/', "{% url 'profile.upload_photo' user_this.id %}") content = content.replace('Create / update your gravatar', "Change profile photo") with open(file_path, 'w') as f: f.write(content)
def theme_delete(request): if not request.user.profile.is_superuser: raise Http403 selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 shutil.rmtree(get_theme_root(selected_theme)) if settings.USE_S3_STORAGE: delete_file_from_s3(file=settings.AWS_LOCATION + '/' + settings.THEME_S3_PATH + '/' + selected_theme) msg_string = 'Successfully deleted %s.' % (selected_theme) messages.add_message(request, messages.SUCCESS, _(msg_string)) EventLog.objects.log() return redirect('theme_editor.editor')
def render_to_theme(template_name, dictionary={}, context_instance=Context): """Loads the given template_name and renders it with the given dictionary as context. The template_name may be a string to load a single template using get_template, or it may be a tuple to use select_template to find one of the templates in the list. Returns a string. This shorcut prepends the template_name given with the selected theme's directory """ context_instance.update(dictionary) toggle = 'TOGGLE_TEMPLATE' in context_instance #theme = context_instance['THEME'] theme = get_setting('module', 'theme_editor', 'theme') theme_template = get_theme_template(template_name, theme=theme) context_instance["THEME_TEMPLATE"] = template_name context_instance["CUSTOM_TEMPLATE"] = False if toggle: t = get_default_template(template_name) else: if isinstance(template_name, (list, tuple)): try: t = select_template(theme_template) except TemplateDoesNotExist: t = get_default_template(template_name) context_instance["CUSTOM_TEMPLATE"] = False else: try: t, origin = get_template(theme_template) if origin and re.search("^%s.+" % get_theme_root(), origin.name): context_instance["CUSTOM_TEMPLATE"] = True if 'homepage.html' in template_name: context_instance["CUSTOM_TEMPLATE"] = False except TemplateDoesNotExist: t = get_default_template(template_name) context_instance["CUSTOM_TEMPLATE"] = False return strip_content_above_doctype(t.render(context_instance))
def handle(self, appnames, **options): try: verbosity = int(options['verbosity']) except: verbosity = 1 if not appnames: appnames = django_settings.INSTALLED_APPS # exclude django native apps appnames = [app for app in appnames if not app.startswith('django.')] for appname in appnames: print() print('Processing for %s ...' % appname) if appname.startswith('addons.'): json_file = os.path.abspath(os.path.join( django_settings.PROJECT_ROOT, os.path.join(*appname.split('.')), 'settings.json' )) elif appname.startswith('themes.'): theme_root = get_theme_root(appname[len('themes.'):]) json_file = os.path.join(theme_root, 'settings.json') else: json_file = os.path.abspath(os.path.join( django_settings.TENDENCI_ROOT, '..', os.path.join(*appname.split('.')), 'settings.json' )) if os.path.isfile(json_file): with open(json_file, 'r') as f: try: settings = json.loads(f.read()) except ValueError as e: print("Error updating setting for %s/settings.json" % appname) print(e) continue if settings: self.update_settings(settings, verbosity=verbosity)
def get_template_list(): """ Get a list of files from the template directory that begin with 'default-' """ file_list = [] theme_dir = get_theme_root() template_dir = os.path.join(theme_dir, 'templates') if os.path.isdir(template_dir): item_list = os.listdir(template_dir) else: item_list = [] for item in item_list: current_item = os.path.join(template_dir, item) path_split = os.path.splitext(current_item) extension = path_split[1] base_name = os.path.basename(path_split[0]) if os.path.isfile(current_item): if extension == ".html" and "default-" in base_name: base_display_name = base_name[8:].replace('-',' ').title() file_list.append((item,base_display_name,)) return sorted(file_list)
def handle_simple(cls, path, local_only, template=None, theme=None): active_theme = get_active_theme() theme = get_theme(active_theme) global _cached_theme_search_info cached_theme, theme_search_info = _cached_theme_search_info # If the theme changed or the user is previewing a different theme, # update _cached_theme_search_info. # Note that _cached_theme_search_info may be shared between multiple # threads, so you must be careful when reading/writing # _cached_theme_search_info to ensure that writes in one thread cannot # cause unexpected behavior in another thread that is reading/writing # _cached_theme_search_info at the same time. if cached_theme != theme: theme_search_info = [] for cur_theme in get_theme_search_order(theme): if is_builtin_theme(cur_theme): cur_theme_dir = get_builtin_theme_dir(cur_theme) static_path = os.path.join(settings.STATIC_ROOT, 'themes', cur_theme_dir) if not os.path.isdir(static_path): continue local_static_url = '%sthemes/%s/' % ( settings.LOCAL_STATIC_URL, cur_theme_dir) static_url = '%sthemes/%s/' % (settings.STATIC_URL, cur_theme_dir) theme_search_info.append( (static_path, local_static_url, static_url)) else: cur_theme_root = get_theme_root(cur_theme) for static_dir in ['media', 'static']: static_path = os.path.join(cur_theme_root, static_dir) if not os.path.isdir(static_path): continue local_static_url = static_url = '/themes/' + cur_theme + '/' + static_dir + '/' if settings.USE_S3_STORAGE: static_url = '%s/%s/%s/themes/%s/%s/' % ( settings.S3_ROOT_URL, settings.AWS_STORAGE_BUCKET_NAME, settings.AWS_LOCATION, cur_theme, static_dir) theme_search_info.append( (static_path, local_static_url, static_url)) if theme == active_theme: _cached_theme_search_info = (theme, theme_search_info) # Search for static file in themes for static_path, local_static_url, static_url in theme_search_info: if not os.path.exists(os.path.join(static_path, path)): continue return urljoin((local_static_url if local_only else static_url), quote(path)) # Warn about static files that don't exist in either a theme or # STATIC_ROOT if not os.path.exists(os.path.join(settings.STATIC_ROOT, path)): if not template: call = ('local_static' if local_only else 'static') warn('%s() call references non-existent static path "%s"' % (call, path)) else: tag = ('{% local_static %}' if local_only else '{% static %}') theme_str = ('theme "%s"' % (theme) if theme else 'an installed Django app') warn( '%s in template "%s" in %s references non-existent static path "%s"' % (tag, template, theme_str, path)) # Handle {% local_static %} for files not found in a theme if local_only: return urljoin(settings.LOCAL_STATIC_URL, quote(path)) # Default to standard Django {% static %} behavior return super(ThemeStaticNode, cls).handle_simple(path)
import codecs import urllib # django from django import forms from django.core.files import File from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.core.cache import cache # local from tendenci.apps.theme.utils import get_theme_root, get_theme, theme_choices from tendenci.apps.theme_editor.utils import archive_file from tendenci.libs.boto_s3.utils import save_file_to_s3 THEME_ROOT = get_theme_root() FILE_EXTENTIONS = ( '.html', '.js', '.css', '.less', '.jpg', '.jpeg', '.png', '.ico', '.gif', '.txt', '.xml', '.kml', '.eot', '.ttf',
def migrate_customized_directories_templates(): """ Update those directories templates that are pulled to sites directories/add.html, directories/edit.html: ============================================ Replace: <script type="text/javascript" src="{% static 'js/email-verification.js' %}"> </script> With: <script type="text/javascript" src="{% static 'js/email-verification.js' %}"> </script> <script type="text/javascript">{% include 'directories/include/get_subcategories.js' %} </script> directories/meta.html: ====================== Replace: {% with directory.category_set as directory_cat %} With: {% with directory.cat as directory_cat %} Replace: {% if directory_cat.category %} With: {% if directory_cat %} Replace: category={{ directory_cat.category.pk }}">{{ directory_cat.category }} With: cat={{ directory_cat.pk }}">{{ directory_cat.name }} Replace: {% if directory_cat.sub_category %} With: {% if directory.sub_cat %} Replace: sub_category={{ directory_cat.sub_category.pk }}">{{ directory_cat.sub_category }} With: cat={{ directory_cat.pk }}&sub_cat={{ directory.sub_cat.pk }}">{{ directory.sub_cat.name }} Remove: <li> <a href="{% url 'category.update' directory.opt_app_label directory.opt_module_name directory.pk %}">{% trans "Edit Categories" %}</a> </li> directories/search-form.html: ====================== # Remove: {% for form.category in form.category_list %} {{ form.category.name }} {% endfor %} Replace: form.category With: form.cat Replace: form.sub_category With: form.sub_cat directories/search.html: ================= Replace: var $catAndSubcatSelect = $('#id_category, #id_sub_category') With: var $catAndSubcatSelect = $('#id_cat, #id_sub_cat') directories/top_nav_items.html: ======================== Replace: <li class="content-item"> <span class="app-name"> <a href="{% url 'category.update' app_object.opt_app_label app_object.opt_module_name app_object.pk %}">{% trans "Edit Categories" %}</a> </span> </li> With: {% if request.user.is_superuser %} <li class="content-item"> <span class="app-name"> <a href="{% url 'admin:directories_category_changelist' %}">{% trans "Manage Categories" %}</a> </span> </li> {% endif %} """ import re from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() # directories/add.html and edit.html files_list = ['{}/templates/directories/add.html'.format(dir_path), '{}/templates/directories/edit.html'.format(dir_path)] for file_path in files_list: if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() # add js link p = r'{0}\s*{1}'.format(re.escape('<script type="text/javascript" src="{% static \'js/email-verification.js\' %}">'), re.escape('</script>')) content = re.sub(p, '{0}\n{1}'.format('<script type="text/javascript" src="{% static \'js/email-verification.js\' %}"> </script>', '<script type="text/javascript">\n{% include \'directories/include/get_subcategories.js\' %} \n</script>'), content) with open(file_path, 'w') as f: # save the updated content back to file f.write(content) # directories/meta.html file_path = '{}/templates/directories/meta.html'.format(dir_path) if os.path.isfile(file_path): find_replace_list = [('{% with directory.category_set as directory_cat %}', '{% with directory.cat as directory_cat %}'), ('{% if directory_cat.category %}', '{% if directory_cat %}'), ('category={{ directory_cat.category.id }}">{{ directory_cat.category }}', 'cat={{ directory_cat.pk }}">{{ directory_cat.name }}'), ('{% if directory_cat.sub_category %}', '{% if directory.sub_cat %}'), ('sub_category={{ directory_cat.sub_category.id }}">{{ directory_cat.sub_category }}', 'cat={{ directory_cat.pk }}&sub_cat={{ directory.sub_cat.pk }}">{{ directory.sub_cat.name }}'), ] with open(file_path, 'r') as f: content = f.read() for (string_to_find, string_to_replace) in find_replace_list: content = content.replace(string_to_find, string_to_replace) p = r'{0}\s+{1}\s+{2}'.format(re.escape('<li>'), re.escape("""<a href="{% url 'category.update' directory.opt_app_label directory.opt_module_name directory.pk %}">{% trans "Edit Categories" %}</a>"""), re.escape('</li>')) content = re.sub(p, '', content) with open(file_path, 'w') as f: f.write(content) # directories/search-form.html file_path = '{}/templates/directories/search-form.html'.format(dir_path) if os.path.isfile(file_path): find_replace_list = [('form.category', 'form.cat'), ('form.sub_category', 'form.sub_cat') ] with open(file_path, 'r') as f: content = f.read() # remove p = r'{0}\s*{1}\s*{2}'.format(re.escape('{% for form.category in form.category_list %}'), re.escape(' {{ form.category.name }}'), re.escape('{% endfor %}')) content = re.sub(p, '', content) for (string_to_find, string_to_replace) in find_replace_list: content = content.replace(string_to_find, string_to_replace) with open(file_path, 'w') as f: f.write(content) # directories/search.html file_path = '{}/templates/directories/search.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() content = content.replace("var $catAndSubcatSelect = $('#id_category, #id_sub_category')", "var $catAndSubcatSelect = $('#id_cat, #id_sub_cat')") with open(file_path, 'w') as f: f.write(content) #directories/top_nav_items.html file_path = '{}/templates/directories/top_nav_items.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() p = r'{0}\s+{1}\s+{2}\s+{3}\s+{4}'.format( re.escape('<li class="content-item">'), re.escape('<span class="app-name">'), re.escape("""<a href="{% url 'category.update' app_object.opt_app_label app_object.opt_module_name app_object.pk %}">{% trans "Edit Categories" %}</a>"""), re.escape('</span>'), re.escape('</li>')) manage_cat = """ {% if request.user.is_superuser %} <li class="content-item"> <span class="app-name"> <a href="{% url 'admin:directories_category_changelist' %}">{% trans "Manage Categories" %}</a> </span> </li> {% endif %} """ content = re.sub(p, manage_cat, content) with open(file_path, 'w') as f: f.write(content)
def migrate_categories_for_templates(): """ Migrate categories for templates pulled down to the site. directories/meta.html ============================================ Replace: {% with directory.cat as directory_cat %} {% if directory_cat %} <li> <ul class="list-inline"> <li><strong>{% trans "Category:" %}</strong> <a href="{% url 'directories' %}?cat={{ directory_cat.pk }}">{{ directory_cat.name }}</a></li> {% if directory.sub_cat %} <li>|</li> <li><strong>{% trans "Subcategory:" %}</strong> <a href="{% url 'directories' %}?cat={{ directory_cat.pk }}&sub_cat={{ directory.sub_cat.pk }}">{{ directory.sub_cat.name }}</a></li> {% endif %} </ul> </li> {% endif %} {% endwith %} with: {% with directory.cats.all as directory_cats %} {% if directory_cats %} <li> <ul class="list-inline"> <li><strong>{% trans "Category:" %}</strong> {% for cat in directory_cats %} <a href="{% url 'directories' %}?cat={{ cat.pk }}">{{ cat.name }}</a>{% if not forloop.last %}, {% endif %} {% endfor %} </li> {% with directory.sub_cats.all as directory_sub_cats %} {% if directory_sub_cats %} <li>|</li> <li><strong>{% trans "Subcategory:" %}</strong> {% for sub_cat in directory_sub_cats %} <a href="{% url 'directories' %}?sub_cat={{ sub_cat.pk }}">{{ sub_cat.name }}</a>{% if not forloop.last %}, {% endif %} {% endfor %} </li> {% endif %} {% endwith %} </ul> </li> {% endif %} {% endwith %} """ import re from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() file_path = '{}/templates/directories/meta.html'.format(dir_path) replace_with = """ {% with directory.cats_list as cats_list %} {% if cats_list %} <li> {% for cat, sub_cats in cats_list %} <ul class="list-inline"> <li><strong>{% trans "Category:" %}</strong> <a href="{% url 'directories' %}?cat={{ cat.pk }}">{{ cat.name }}</a> </li> {% if sub_cats %} <li>|</li> <li><strong>{% trans "Subcategory:" %}</strong> {% for sub_cat in sub_cats %} <a href="{% url 'directories' %}?sub_cat={{ sub_cat.pk }}">{{ sub_cat.name }}</a>{% if not forloop.last %}, {% endif %} {% endfor %} </li> {% endif %} </ul> {% endfor %} </li> {% endif %} {% endwith %} """ p = r'\{% with directory.cat as directory_cat %\}[\d\D\s\S\w\W]*?\{% endwith %\}' if os.path.isfile(file_path): print('Updating categories for file directories/meta.html') with open(file_path, 'r') as f: content = f.read() content = re.sub(p, replace_with, content) with open(file_path, 'w') as f: f.write(content)
def edit_file(request, form_class=FileForm, template_name="theme_editor/index.html"): selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) # get the default file and clean up any input default_file = request.GET.get("file", DEFAULT_FILE) if default_file: default_file = default_file.replace('\\', '/') default_file = default_file.strip('/') default_file = default_file.replace('////', '/') default_file = default_file.replace('///', '/') default_file = default_file.replace('//', '/') theme_root = get_theme_root(selected_theme) if not is_valid_path(theme_root, default_file): raise Http403 theme_read_only = is_theme_read_only(selected_theme) if request.is_ajax() and request.method == "POST": if theme_read_only: raise Http403 file_form = form_class(request.POST) response_status = 'FAIL' response_message = _('Cannot update file.') if file_form.is_valid(): if file_form.save(theme_root, selected_theme, default_file, request): response_status = 'SUCCESS' response_message = str(_('Your changes have been saved.')) EventLog.objects.log() response = json.dumps({ 'status': response_status, 'message': response_message }) return HttpResponse(response, content_type='application/json') is_file = os.path.isfile(os.path.join(theme_root, default_file)) is_dir = os.path.isdir(os.path.join(theme_root, default_file)) if is_file: pass elif is_dir: # if default_file is a directory then append the # trailing slash so we can get the dirname below default_file = '%s/' % default_file else: # if the default_file is not a directory or file within # the themes folder then return a 404 raise Http404( _("Custom template not found. Make sure you've copied over the themes to the THEME_DIR." )) # get the current file name current_file = os.path.basename(default_file) # get file ext name = current_file.split('/')[-1] ext = name.split('.')[-1] stylesheets = ['css', 'less'] # get the present working directory # and make sure they cannot list root pwd = os.path.dirname(default_file) if pwd == '/': pwd = '' # make sure the path is still valid after stripping off the file name if not is_valid_path(theme_root, pwd): raise Http403 current_file_path = os.path.join(pwd, current_file) # get the previous directory name and path prev_dir = '/' prev_dir_name = 'theme base' pwd_split = pwd.split('/') if len(pwd_split) > 1: prev_dir_name = pwd_split[-2] pwd_split.pop() prev_dir = '/'.join(pwd_split) elif not pwd_split[0]: prev_dir = '' # get the directory list dirs = get_dir_list(theme_root, pwd) # get the file list files, non_editable_files = get_file_list(theme_root, pwd) all_files_folders = get_all_files_list(theme_root, selected_theme) # non-deletable files non_deletable_files = [ 'homepage.html', 'default.html', 'footer.html', 'header.html', 'sidebar.html', 'nav.html', 'styles.less', 'styles.css' ] # get the number of themes in the themes directory on the site theme_count = len([i for i in theme_choices()]) # get a list of revisions archives = ThemeFileVersion.objects.filter( relative_file_path=current_file_path).order_by("-create_dt") # New templates created by clicking the New Template" button are blank. # Add a space for the blank template to make it editable. content = get_file_content(theme_root, selected_theme, current_file_path) or ' ' file_form = form_class({'content': content}) theme_form = ThemeSelectForm(initial={'theme_edit': selected_theme}) return render_to_resp(request=request, template_name=template_name, context={ 'file_form': file_form, 'theme_form': theme_form, 'current_theme': selected_theme, 'current_file_path': current_file_path, 'current_file': current_file, 'prev_dir_name': prev_dir_name, 'prev_dir': prev_dir, 'pwd': pwd, 'dirs': dirs, 'files': files, 'non_editable_files': non_editable_files, 'non_deletable_files': non_deletable_files, 'theme_count': theme_count, 'archives': archives, 'is_file': is_file, 'is_dir': is_dir, 'theme_read_only': theme_read_only, 'can_copy_theme': (not is_base_theme(selected_theme)), 'all_files_folders': all_files_folders, 'ext': ext, 'stylesheets': stylesheets, })
def migrate_customized_jobs_templates(): """ Update those jobs templates that are pulled to sites jobs/add.html, jobs/edit.html: ============================= Remove: <fieldset class="boxy-grey" > <legend id="category-title" style="cursor: pointer"><span>+</span> {% trans 'Category' %}</legend> <div id="category-form"> {{ categoryform|styled_form }} </div> </fieldset> Replace: <script type="text/javascript" src="{% static 'js/email-verification.js' %}"> </script> With: <script type="text/javascript" src="{% static 'js/email-verification.js' %}"> </script> <script type="text/javascript">{% include 'jobs/include/get_subcategories.js' %} </script> jobs/meta.html: =============== Replace: {% with job.category_set as job_cat %} With: {% with job.cat as job_cat %} Replace: {% if job_cat.category %} With: {% if job_cat %} Replace: categories={{ job_cat.category.pk }}">{{ job_cat.category }} With: cat={{ job_cat.pk }}">{{ job_cat.name }} Replace: {% if job_cat.sub_category %} With: {% if job.sub_cat %} Replace: subcategories={{ job_cat.sub_category.pk }}">{{ job_cat.sub_category }} With: cat={{ job_cat.pk }}&sub_cat={{ job.sub_cat.pk }}">{{ job.sub_cat.name }} Remove: <li> <a href="{% url 'category.update' job.opt_app_label job.opt_module_name job.pk %}">{% trans "Edit Categories" %}</a> </li> jobs/search-form.html: ====================== Replace: form.categories With: form.cat Replace: form.subcategories With: form.sub_cat jobs/search.html: ================= Replace: var $catAndSubcatSelect = $('#id_categories, #id_subcategories') With: var $catAndSubcatSelect = $('#id_cat, #id_sub_cat') jobs/top_nav_items.html: ======================== Replace: <li class="content-item"> <span class="app-name"> <a href="{% url 'category.update' app_object.opt_app_label job.opt_module_name app_object.pk %}">{% trans "Edit Categories" %}</a> </span> </li> With: {% if request.user.is_superuser %} <li class="content-item"> <span class="app-name"> <a href="{% url 'admin:jobs_category_changelist' %}">{% trans "Manage Categories" %}</a> </span> </li> {% endif %} """ import re from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() # jobs/add.html and edit.html files_list = ['{}/templates/jobs/add.html'.format(dir_path), '{}/templates/jobs/edit.html'.format(dir_path)] for file_path in files_list: if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() # remove categoryform p = r'{0}([\d\D\s\S\w\W]*?){1}([\d\D\s\S\w\W]*?){2}'.format(re.escape('<fieldset class="boxy-grey" >'), re.escape('{{ categoryform|styled_form }}'), re.escape('</fieldset>')) content = re.sub(p, '', content) # add js link p = r'{0}\s*{1}'.format(re.escape('<script type="text/javascript" src="{% static \'js/email-verification.js\' %}">'), re.escape('</script>')) content = re.sub(p, '{0}\n{1}'.format('<script type="text/javascript" src="{% static \'js/email-verification.js\' %}"> </script>', '<script type="text/javascript">{% include \'jobs/include/get_subcategories.js\' %} </script>)'), content) with open(file_path, 'w') as f: # save the updated content back to file f.write(content) # jobs/meta.html file_path = '{}/templates/jobs/meta.html'.format(dir_path) if os.path.isfile(file_path): find_replace_list = [('{% with job.category_set as job_cat %}', '{% with job.cat as job_cat %}'), ('{% if job_cat.category %}', '{% if job_cat %}'), ('categories={{ job_cat.category.pk }}">{{ job_cat.category }}', 'cat={{ job_cat.pk }}">{{ job_cat.name }}'), ('{% if job_cat.sub_category %}', '{% if job.sub_cat %}'), ('subcategories={{ job_cat.sub_category.pk }}">{{ job_cat.sub_category }}', 'cat={{ job_cat.pk }}&sub_cat={{ job.sub_cat.pk }}">{{ job.sub_cat.name }}'), ] with open(file_path, 'r') as f: content = f.read() for (string_to_find, string_to_replace) in find_replace_list: content = content.replace(string_to_find, string_to_replace) p = r'{0}\s+{1}\s+{2}'.format(re.escape('<li>'), re.escape("""<a href="{% url 'category.update' job.opt_app_label job.opt_module_name job.pk %}">{% trans "Edit Categories" %}</a>"""), re.escape('</li>')) content = re.sub(p, '', content) with open(file_path, 'w') as f: f.write(content) # jobs/search-form.html file_path = '{}/templates/jobs/search-form.html'.format(dir_path) if os.path.isfile(file_path): find_replace_list = [('form.categories', 'form.cat'), ('form.subcategories', 'form.sub_cat') ] with open(file_path, 'r') as f: content = f.read() for (string_to_find, string_to_replace) in find_replace_list: content = content.replace(string_to_find, string_to_replace) with open(file_path, 'w') as f: f.write(content) # jobs/search.html file_path = '{}/templates/jobs/search.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() content = content.replace("var $catAndSubcatSelect = $('#id_categories, #id_subcategories')", "var $catAndSubcatSelect = $('#id_cat, #id_sub_cat')") with open(file_path, 'w') as f: f.write(content) #jobs/top_nav_items.html file_path = '{}/templates/jobs/top_nav_items.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() p = r'{0}\s+{1}\s+{2}\s+{3}\s+{4}'.format( re.escape('<li class="content-item">'), re.escape('<span class="app-name">'), re.escape("""<a href="{% url 'category.update' app_object.opt_app_label job.opt_module_name app_object.pk %}">{% trans "Edit Categories" %}</a>"""), re.escape('</span>'), re.escape('</li>')) manage_cat = """ {% if request.user.is_superuser %} <li class="content-item"> <span class="app-name"> <a href="{% url 'admin:jobs_category_changelist' %}">{% trans "Manage Categories" %}</a> </span> </li> {% endif %} """ content = re.sub(p, manage_cat, content) with open(file_path, 'w') as f: f.write(content)
def update_jquery_in_theme(apps, schema_editor): """ Upgrade jquery for templates and js in theme's directory. """ import re import os import sys from collections import OrderedDict from tendenci.apps.theme.utils import get_theme_root theme_dir = get_theme_root() # Check base.html file_path = '{}/templates/base.html'.format(theme_dir) if os.path.isfile(file_path): content = '' file_changed = False with open(file_path, 'r') as f: content = f.read() p = r'({0}[\d\D\s\S\w\W]*?<script (type="text/javascript" )?)({1})([\d\D\s\S\w\W]*?{2})'.format( re.escape('{% block jquery_script %}'), re.escape( 'src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>' ), re.escape('{% endblock jquery_script %}')) if re.search(p, content): # Ensure no sites will be broken by including query-migrate content = re.sub(p, r'\1{}\4'.format('src="//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>' + \ '\n\t<script src="https://code.jquery.com/jquery-migrate-3.1.0.min.js"></script>'), content) file_changed = True if file_changed: with open(file_path, 'w') as f: f.write(content) # Update custom templates items_find_replace = OrderedDict([ ('.click(function', '.on("click", function'), ('.mouseenter(function', '.on("mouseenter", function'), ('.removeAttr(\'multiple\')', ".prop('multiple', false )"), ('.removeAttr(\'disabled\')', ".prop('disabled', false )"), ('.removeAttr(\'checked\')', ".prop('checked', false )"), ('.removeAttr(\'required\')', ".prop('required', false )"), ('.removeAttr(\'id\')', ".prop('id', false )"), #('.unbind(', '.off('), #('.bind(', '.on('), ('$.parseJSON', 'JSON.parse'), ('.change(function', '.on("change", function'), ('.submit(function', '.on("submit", function'), ('.keyup(function', '.on("keyup", function'), ('.keydown(', '.on("keydown", '), ('.blur(', '.on("blur", '), ('.focus()', '.trigger("focus")'), ('.focus(function', '.on("focus", function'), ('.unload(', '.on("unload", '), ('.load(', '.on("load", '), ]) items_to_check = items_find_replace.keys() theme_templatges_dir = os.path.join(theme_dir, 'templates') #theme_media_dir = os.path.join(theme_dir, 'media') for directory in [ theme_templatges_dir, ]: for root, dirs, files in os.walk(directory): for file_name in files: if os.path.splitext(file_name)[1] in ('.html', '.js'): file_path = os.path.join(root, file_name) file_changed = False with open(file_path, 'r') as f: try: content = f.read() except: print( "Error on reading file {}:".format(file_path), sys.exc_info()[0]) raise for item in items_to_check: if item in content: file_changed = True break for k, v in items_find_replace.items(): content = content.replace(k, v) if file_changed: with open(file_path, 'w') as f: f.write(content)
def migrate_customized_jobs_templates(): """ Update those jobs templates that are pulled to sites jobs/add.html, jobs/edit.html: ============================= Remove: <fieldset class="boxy-grey" > <legend id="category-title" style="cursor: pointer"><span>+</span> {% trans 'Category' %}</legend> <div id="category-form"> {{ categoryform|styled_form }} </div> </fieldset> Replace: <script type="text/javascript" src="{% static 'js/email-verification.js' %}"> </script> With: <script type="text/javascript" src="{% static 'js/email-verification.js' %}"> </script> <script type="text/javascript">{% include 'jobs/include/get_subcategories.js' %} </script> jobs/meta.html: =============== Replace: {% with job.category_set as job_cat %} With: {% with job.cat as job_cat %} Replace: {% if job_cat.category %} With: {% if job_cat %} Replace: categories={{ job_cat.category.pk }}">{{ job_cat.category }} With: cat={{ job_cat.pk }}">{{ job_cat.name }} Replace: {% if job_cat.sub_category %} With: {% if job.sub_cat %} Replace: subcategories={{ job_cat.sub_category.pk }}">{{ job_cat.sub_category }} With: cat={{ job_cat.pk }}&sub_cat={{ job.sub_cat.pk }}">{{ job.sub_cat.name }} Remove: <li> <a href="{% url 'category.update' job.opt_app_label job.opt_module_name job.pk %}">{% trans "Edit Categories" %}</a> </li> jobs/search-form.html: ====================== Replace: form.categories With: form.cat Replace: form.subcategories With: form.sub_cat jobs/search.html: ================= Replace: var $catAndSubcatSelect = $('#id_categories, #id_subcategories') With: var $catAndSubcatSelect = $('#id_cat, #id_sub_cat') jobs/top_nav_items.html: ======================== Replace: <li class="content-item"> <span class="app-name"> <a href="{% url 'category.update' app_object.opt_app_label job.opt_module_name app_object.pk %}">{% trans "Edit Categories" %}</a> </span> </li> With: {% if request.user.is_superuser %} <li class="content-item"> <span class="app-name"> <a href="{% url 'admin:jobs_category_changelist' %}">{% trans "Manage Categories" %}</a> </span> </li> {% endif %} """ import re from tendenci.apps.theme.utils import get_theme_root dir_path = get_theme_root() # jobs/add.html and edit.html files_list = [ '{}/templates/jobs/add.html'.format(dir_path), '{}/templates/jobs/edit.html'.format(dir_path) ] for file_path in files_list: if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() # remove categoryform p = r'{0}([\d\D\s\S\w\W]*?){1}([\d\D\s\S\w\W]*?){2}'.format( re.escape('<fieldset class="boxy-grey" >'), re.escape('{{ categoryform|styled_form }}'), re.escape('</fieldset>')) content = re.sub(p, '', content) # add js link p = r'{0}\s*{1}'.format( re.escape( '<script type="text/javascript" src="{% static \'js/email-verification.js\' %}">' ), re.escape('</script>')) content = re.sub( p, '{0}\n{1}'.format( '<script type="text/javascript" src="{% static \'js/email-verification.js\' %}"> </script>', '<script type="text/javascript">{% include \'jobs/include/get_subcategories.js\' %} </script>)' ), content) with open(file_path, 'w') as f: # save the updated content back to file f.write(content) # jobs/meta.html file_path = '{}/templates/jobs/meta.html'.format(dir_path) if os.path.isfile(file_path): find_replace_list = [ ('{% with job.category_set as job_cat %}', '{% with job.cat as job_cat %}'), ('{% if job_cat.category %}', '{% if job_cat %}'), ('categories={{ job_cat.category.pk }}">{{ job_cat.category }}', 'cat={{ job_cat.pk }}">{{ job_cat.name }}'), ('{% if job_cat.sub_category %}', '{% if job.sub_cat %}'), ('subcategories={{ job_cat.sub_category.pk }}">{{ job_cat.sub_category }}', 'cat={{ job_cat.pk }}&sub_cat={{ job.sub_cat.pk }}">{{ job.sub_cat.name }}' ), ] with open(file_path, 'r') as f: content = f.read() for (string_to_find, string_to_replace) in find_replace_list: content = content.replace(string_to_find, string_to_replace) p = r'{0}\s+{1}\s+{2}'.format( re.escape('<li>'), re.escape( """<a href="{% url 'category.update' job.opt_app_label job.opt_module_name job.pk %}">{% trans "Edit Categories" %}</a>""" ), re.escape('</li>')) content = re.sub(p, '', content) with open(file_path, 'w') as f: f.write(content) # jobs/search-form.html file_path = '{}/templates/jobs/search-form.html'.format(dir_path) if os.path.isfile(file_path): find_replace_list = [('form.categories', 'form.cat'), ('form.subcategories', 'form.sub_cat')] with open(file_path, 'r') as f: content = f.read() for (string_to_find, string_to_replace) in find_replace_list: content = content.replace(string_to_find, string_to_replace) with open(file_path, 'w') as f: f.write(content) # jobs/search.html file_path = '{}/templates/jobs/search.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() content = content.replace( "var $catAndSubcatSelect = $('#id_categories, #id_subcategories')", "var $catAndSubcatSelect = $('#id_cat, #id_sub_cat')") with open(file_path, 'w') as f: f.write(content) #jobs/top_nav_items.html file_path = '{}/templates/jobs/top_nav_items.html'.format(dir_path) if os.path.isfile(file_path): with open(file_path, 'r') as f: content = f.read() p = r'{0}\s+{1}\s+{2}\s+{3}\s+{4}'.format( re.escape('<li class="content-item">'), re.escape('<span class="app-name">'), re.escape( """<a href="{% url 'category.update' app_object.opt_app_label job.opt_module_name app_object.pk %}">{% trans "Edit Categories" %}</a>""" ), re.escape('</span>'), re.escape('</li>')) manage_cat = """ {% if request.user.is_superuser %} <li class="content-item"> <span class="app-name"> <a href="{% url 'admin:jobs_category_changelist' %}">{% trans "Manage Categories" %}</a> </span> </li> {% endif %} """ content = re.sub(p, manage_cat, content) with open(file_path, 'w') as f: f.write(content)