How to build your own sub-theme (7.x-3.x)

本文介绍如何在Drupal7中创建Zen主题的子主题。包括设置子主题位置、编辑基本信息、选择布局方式、修改模板文件等内容。

The base Zen theme is designed to be easily extended by its sub-themes. You shouldn't modify any of the CSS or PHP files in the zen/ folder; but instead you should create a sub-theme of zen which is located in a folder outside of the root zen/ folder. The examples below assume zen and your sub-theme will be installed in sites/all/themes/, but any valid theme directory is acceptable (read the sites/default/default.settings.php for more info.)

IMPORTANT NOTE: In Drupal 7, the theme system caches which template files and which theme functions should be called. This means that if you add a new theme, preprocess or process function to your template.php file or add a new template (.tpl.php) file to your sub-theme, you will need to rebuild the "theme registry." See http://drupal.org/node/173880#theme-registry

Drupal 7 also stores a cache of the data in .info files. If you modify any lines in your sub-theme's .info file, you MUST refresh Drupal 7's cache by simply visiting the Appearance page at admin/appearance.

  1. Setup the location for your new sub-theme.

    Copy the STARTERKIT folder out of the zen/ folder and rename it to be your new sub-theme. IMPORTANT: The name of your sub-theme must start with an alphabetic character and can only contain lowercase letters, numbers and underscores.

    For example, copy the sites/all/themes/zen/STARTERKIT folder and rename it as sites/all/themes/foo.

    Why? Each theme should reside in its own folder. To make it easier to upgrade Zen, sub-themes should reside in a folder separate from the base theme.

  2. Setup the basic information for your sub-theme.

    In your new sub-theme folder, rename the STARTERKIT.info.txt file to include the name of your new sub-theme and remove the ".txt" extension. Then edit the .info file by editing the name and description field.

    For example, rename the foo/STARTERKIT.info file to foo/foo.info. Edit the foo.info file and change "name = Zen Sub-theme Starter Kit" to "name = Foo" and "description = Read..." to "description = A Zen sub-theme".

    Why? The .info file describes the basic things about your theme: its name, description, features, template regions, CSS files, and JavaScript files. See the Drupal 7 Theme Guide for more info

    Then, visit your site's Appearance page at admin/appearance to refresh Drupal 7's cache of .info file data.

  3. Choose your preferred page layout method or grid system.

    By default your new sub-theme is using a fixed-width layout. If you want a liquid layout for your theme, delete the unneeded layout-fixed.css and layout-fixed-rtl.css files and edit your sub-theme's .info file and replace the reference to layout-fixed.css with layout-liquid.css.

    For example, edit foo/foo.info and change this line:
    stylesheets[all][]   = css/layout-fixed.css
    to:
    stylesheets[all][]   = css/layout-liquid.css

    Why? The "stylesheets" lines in your .info file describe the media type and path to the CSS file you want to include. The format for these lines is: stylesheets[MEDIA][] = path/to/file.css

    Alternatively, if you are more familiar with a different CSS layout method, such as Blueprint or 960.gs, you can replace the "css/layout-fixed.css" line in your .info file with a line pointing at your choice of layout CSS file.

    Then, visit your site's Appearance page at admin/appearance to refresh Drupal 7's cache of .info file data.

  4. Edit your sub-theme to use the proper function names.

    Edit the template.php and theme-settings.php files in your sub-theme's folder; replace ALL occurrences of "STARTERKIT" with the name of your sub-theme.

    For example, edit foo/template.php and foo/theme-settings.php and replace every occurrence of "STARTERKIT" with "foo".

    It is recommended to use a text editing application with search and "replace all" functionality.

  5. Set your website's default theme.

    Log in as an administrator on your Drupal site, go to the Appearance page at admin/appearance and click the "Enable and set default" link next to your new sub-theme.

    Optional steps:

  6. Modify the markup in Zen core's template files.

    If you decide you want to modify any of the .tpl.php template files in the zen folder, copy them to your sub-theme's folder before making any changes. And then rebuild the theme registry.

    For example, copy zen/templates/page.tpl.php to foo/templates/page.tpl.php.

  7. Modify the markup in Drupal's search form.

    Copy the search-block-form.tpl.php template file from the modules/search/ folder and place it in your sub-theme's template folder. And then rebuild the theme registry.

    You can find a full list of Drupal templates that you can override in the templates/README.txt file or http://drupal.org/node/190815

    Why? In Drupal 7 theming, if you want to modify a template included by a module, you should copy the template file from the module's directory to your sub-theme's template directory and then rebuild the theme registry. See the Drupal 7 Theme Guide for more info.

  8. Further extend your sub-theme.

    Discover further ways to extend your sub-theme by reading Zen's documentation and Drupal 7's Theme Guide.

#!/usr/bin/env python """ Defines a CLI for compiling Sass (both default and themed) into CSS. Should be run from the root of edx-platform using `npm run` wrapper. Requirements for this scripts are stored in requirements/edx/assets.in. Get more details: npm run compile-sass -- --help npm run compile-sass -- --dry Setup (Tutor and Devstack will do this for you): python -m venv venv . venv/bin/activate pip install -r requirements/edx/assets.txt Usage: npm run compile-sass # prod, no args npm run compile-sass -- ARGS # prod, with args npm run compile-sass-dev # dev, no args npm run compile-sass-dev -- ARGS # dev, with args This script is intentionally implemented in a very simplistic way. It prefers repetition over abstraction, and its dependencies are minimal (just click and libsass-python, ideally). We do this because: * If and when we migrate from libsass-python to something less ancient like node-sass or dart-sass, we will want to re-write this script in Bash or JavaScript so that it can work without any backend tooling. By keeping the script dead simple, that will be easier. * The features this script supports (legacy frontends & comprehensive theming) are on the way out, in favor of micro-frontends, branding, and Paragon design tokens. We&#39;re not sure how XBlock view styling will fit into that, but it probably can be much simpler than comprehensive theming. So, we don&#39;t need this script to be modular and extensible. We just need it to be obvious, robust, and easy to maintain until we can delete it. See docs/decisions/0017-reimplement-asset-processing.rst for more details. """ from __future__ import annotations import glob import os import subprocess import sys from pathlib import Path import click # Accept both long- and short-forms of these words, but normalize to long form. # We accept both because edx-platform asset build scripts historically use the short form, # but NODE_ENV uses the long form, so to make them integrate more seamlessly we accept both. NORMALIZED_ENVS = { "prod": "production", "dev": "development", "production": "production", "development": "development", } @click.option( "-T", "--theme-dir", "theme_dirs", metavar="PATH", multiple=True, envvar="COMPREHENSIVE_THEME_DIRS", type=click.Path(path_type=Path), help=( "Consider sub-dirs of PATH as themes. " "Multiple theme dirs are accepted. " "If none are provided, we look at colon-separated paths on the COMPREHENSIVE_THEME_DIRS env var." ), ) @click.option( "-t", "--theme", "themes", metavar="NAME", multiple=True, type=str, help=( "A theme to compile. " "NAME should be a sub-dir of a PATH provided by --theme-dir. " "Multiple themes are accepted. " "If none are provided, all available themes are compiled." ), ) @click.option( "--skip-default", is_flag=True, help="Don&#39;t compile default Sass.", ) @click.option( "--skip-themes", is_flag=True, help="Don&#39;t compile any themes (overrides --theme* options).", ) @click.option( "--skip-lms", is_flag=True, help="Don&#39;t compile any LMS Sass.", ) @click.option( "--skip-cms", is_flag=True, help="Don&#39;t compile any CMS Sass.", ) @click.option( "--env", type=click.Choice(["dev", "development", "prod", "production"]), default="prod", help="Optimize CSS for this environment. Defaults to &#39;prod&#39;.", ) @click.option( "--dry", is_flag=True, help="Print what would be compiled, but don&#39;t compile it.", ) @click.option( "-h", "--help", "show_help", is_flag=True, help="Print this help.", ) @click.command() @click.pass_context def main( context: click.Context, theme_dirs: list[Path], themes: list[str], skip_default: bool, skip_themes: bool, skip_lms: bool, skip_cms: bool, env: str, dry: bool, show_help: bool, ) -> None: """ Compile Sass for edx-platform and its themes. Default Sass is compiled unless explicitly skipped. Additionally, any number of themes may be specified using --theme-dir and --theme. Default CSS is compiled to css/ directories in edx-platform. Themed CSS is compiled to css/ directories in their source themes. """ def compile_sass_dir( message: str, source_root: Path, target_root: Path, includes: list[Path], tolerate_missing: bool = False, ) -> None: """ Compile a directory of Sass into a target CSS directory, and generate any missing RTL CSS. Structure of source dir is mirrored in target dir. IMPLEMENTATION NOTES: ===================== libsass is a C++ library for compiling Sass (ref: https://github.com/sass/libsass). libsass-python is a small PyPI package wrapping libsass, including: * The `_sass` module, which provides direct Python bindings for the C++ library. (ref: https://github.com/sass/libsass-python/blob/0.10.0/pysass.cpp) * The `sass` module, which adds some friendly Pythonic wrapper functions around `_sass`, notably `sass.compile_dirname(...)`. (ref: https://github.com/sass/libsass-python/blob/0.10.0/sass.py#L198-L201) Our legacy Sass code only works with a super old version of libsass (3.3.2,) which is provided to us by a super old version of libsass-python (0.10.0). In this super old libsass-python version: * the `sass` module DOESN&#39;T support Python 3.11+, but * the `_sass` module DOES support Python 3.11+. Upgrading our Sass to work with newer a libsass version would be arduous and would potentially break comprehensive themes, so we don&#39;t want to do that. Forking libsass-python at v0.10.0 and adding Python 3.11+ support would mean adding another repo to the openedx org. Rather than do either of those, we&#39;ve decided to hack around the problem by just reimplementing what we need of `sass.compile_dirname` here, directly on top of the `_sass` C++ binding module. Eventually, we may eschew libsass-python altogether by switching to SassC@3.3.2, a direct CLI for libsass@3.3.2. (ref: https://github.com/sass/sassc). This would be nice because it would allow us to remove Python from the Sass build pipeline entirely. However, it would mean explicitly compiling & installing both libsass and SassC within the edx-platform build environment, which has its own drawbacks. """ # Constants from libsass-python SASS_STYLE_NESTED = 0 _SASS_STYLE_EXPANDED = 1 _SASS_STYLE_COMPACT = 2 SASS_STYLE_COMPRESSED = 3 SASS_COMMENTS_NONE = 0 SASS_COMMENTS_LINE_NUMBERS = 1 # Defaults from libass-python precision = 5 source_map_filename = None custom_functions = [] importers = None use_dev_settings: bool = NORMALIZED_ENVS[env] == "development" fs_encoding: str = sys.getfilesystemencoding() or sys.getdefaultencoding() output_style: int = SASS_STYLE_NESTED if use_dev_settings else SASS_STYLE_COMPRESSED source_comments: int = SASS_COMMENTS_LINE_NUMBERS if use_dev_settings else SASS_COMMENTS_NONE include_paths: bytes = os.pathsep.join(str(include) for include in includes).encode(fs_encoding) click.secho(f" {message}...", fg="cyan") click.secho(f" Source: {source_root}") click.secho(f" Target: {target_root}") if not source_root.is_dir(): if tolerate_missing: click.secho(f" Skipped because source directory does not exist.", fg="yellow") return else: raise FileNotFoundError(f"missing Sass source dir: {source_root}") click.echo(f" Include paths:") for include in includes: click.echo(f" {include}") click.echo(f" Files:") for dirpath, _, filenames in os.walk(str(source_root)): for filename in filenames: if filename.startswith(&#39;_&#39;): continue if not filename.endswith((&#39;.scss&#39;, &#39;.sass&#39;)): continue source = Path(dirpath) / filename target = (target_root / source.relative_to(source_root)).with_suffix(&#39;.css&#39;) click.echo(f" {source} -> {target}") if not dry: # Import _sass late so that this script can be dry-run without installing # libsass, which takes a while as it must be compiled from its C source. from _sass import compile_filename # pylint: disable=protected-access success, output, _ = compile_filename( str(source).encode(fs_encoding), output_style, source_comments, include_paths, precision, source_map_filename, custom_functions, importers, ) output_text = output.decode(&#39;utf-8&#39;) if not success: raise Exception(f"Failed to compile {source}: {output_text}") target.parent.mkdir(parents=True, exist_ok=True) with open(target, &#39;w&#39;, encoding="utf-8") as target_file: target_file.write(output_text) click.secho(f" Done.", fg="green") # For Sass files without explicit RTL versions, generate # an RTL version of the CSS using the rtlcss library. for sass_path in glob.glob(str(source_root) + "/**/*.scss"): if Path(sass_path).name.startswith("_"): # Don&#39;t generate RTL CSS for partials continue if sass_path.endswith("-rtl.scss"): # Don&#39;t generate RTL CSS if the file is itself an RTL version continue if Path(sass_path.replace(".scss", "-rtl.scss")).exists(): # Don&#39;t generate RTL CSS if there is an explicit Sass version for RTL continue click.echo(" Generating missing right-to-left CSS:") source_css_file = sass_path.replace(str(source_root), str(target_root)).replace( ".scss", ".css" ) target_css_file = source_css_file.replace(".css", "-rtl.css") click.echo(f" Source: {source_css_file}") click.echo(f" Target: {target_css_file}") if not dry: subprocess.run(["rtlcss", source_css_file, target_css_file]) click.secho(" Generated.", fg="green") # Information click.secho(f"USING ENV: {NORMALIZED_ENVS[env]}", fg="blue") if dry: click.secho(f"DRY RUN: Will print compile steps, but will not compile anything.", fg="blue") click.echo() # Warnings if show_help: click.echo(context.get_help()) return if skip_lms and skip_cms: click.secho("WARNING: You are skipping both LMS and CMS... nothing will be compiled!", fg="yellow") if skip_default and skip_themes: click.secho("WARNING: You are skipped both default Sass and themed Sass... nothing will be compiled!", fg="yellow") click.echo() # Build a list of theme paths: if skip_themes: theme_paths = [] else: theme_paths = [ theme_dir / theme # For every theme dir, for theme_dir in theme_dirs for theme in ( # for every theme name (if theme names provided), themes or # or for every subdir of theme dirs (if no theme name provided), (theme_dir_entry.name for theme_dir_entry in theme_dir.iterdir()) ) # consider the path a theme if it has a lms/ or cms/ subdirectory. if (theme_dir / theme / "lms").is_dir() or (theme_dir / theme / "cms").is_dir() ] # We expect this script to be run from the edx-platform root. repo = Path(".") if not (repo / "xmodule").is_dir(): # Sanity check: If the xmodule/ folder is missing, we&#39;re definitely not at the root # of edx-platform, so save the user some headache by exiting early. raise Exception(f"{__file__} must be run from the root of edx-platform") # Every Sass compilation will use have these directories as lookup paths, # regardless of theme. common_includes = [ repo / "common" / "static", repo / "common" / "static" / "sass", repo / "node_modules" / "@edx", repo / "node_modules", ] if not skip_default: click.secho(f"Compiling default Sass...", fg="cyan", bold=True) if not skip_lms: compile_sass_dir( "Compiling default LMS Sass", repo / "lms" / "static" / "sass", repo / "lms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], ) compile_sass_dir( "Compiling default certificate Sass", repo / "lms" / "static" / "certificates" / "sass", repo / "lms" / "static" / "certificates" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], ) if not skip_cms: compile_sass_dir( "Compiling default CMS Sass", repo / "cms" / "static" / "sass", repo / "cms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass", ], ) click.secho(f"Done compiling default Sass!", fg="cyan", bold=True) click.echo() for theme in theme_paths: click.secho(f"Compiling Sass for theme at {theme}...", fg="cyan", bold=True) if not skip_lms: compile_sass_dir( "Compiling default LMS Sass with themed partials", repo / "lms" / "static" / "sass", theme / "lms" / "static" / "css", includes=[ *common_includes, theme / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], tolerate_missing=True, ) compile_sass_dir( "Compiling themed LMS Sass as overrides to CSS from previous step", theme / "lms" / "static" / "sass", theme / "lms" / "static" / "css", includes=[ *common_includes, theme / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], tolerate_missing=True, ) compile_sass_dir( "Compiling themed certificate Sass", theme / "lms" / "static" / "certificates" / "sass", theme / "lms" / "static" / "certificates" / "css", includes=[ *common_includes, theme / "lms" / "static" / "sass" / "partials", theme / "lms" / "static" / "sass", ], tolerate_missing=True, ) if not skip_cms: compile_sass_dir( "Compiling default CMS Sass with themed partials", repo / "cms" / "static" / "sass", theme / "cms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", theme / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass", ], tolerate_missing=True, ) compile_sass_dir( "Compiling themed CMS Sass as overrides to CSS from previous step", theme / "cms" / "static" / "sass", theme / "cms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", theme / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass", ], tolerate_missing=True, ) click.secho(f"Done compiling Sass for theme at {theme}!", fg="cyan", bold=True) click.echo() # Report what we did. click.secho("Successfully compiled:", fg="green", bold=True) if not skip_default: click.secho(f" - {repo.absolute()} (default Sass)", fg="green") for theme in theme_paths: click.secho(f" - {theme}", fg="green") if skip_lms: click.secho(f"(skipped LMS)", fg="yellow") if skip_cms: click.secho(f"(skipped CMS)", fg="yellow") if __name__ == "__main__": main(prog_name="npm run compile-sass --") python scripts/compile_sass.py --env=development USING ENV: development Compiling default Sass... Compiling default LMS Sass... Source: lms\static\sass Target: lms\static\css Include paths: common\static common\static\sass node_modules\@edx node_modules lms\static\sass\partials lms\static\sass Files: lms\static\sass\lms-course-rtl.scss -> lms\static\css\lms-course-rtl.css lms\static\sass\lms-course.scss -> lms\static\css\lms-course.css lms\static\sass\lms-footer-edx-rtl.scss -> lms\static\css\lms-footer-edx-rtl.css lms\static\sass\lms-footer-edx.scss -> lms\static\css\lms-footer-edx.css lms\static\sass\lms-footer-rtl.scss -> lms\static\css\lms-footer-rtl.css lms\static\sass\lms-footer.scss -> lms\static\css\lms-footer.css lms\static\sass\lms-main-v1-rtl.scss -> lms\static\css\lms-main-v1-rtl.css Traceback (most recent call last): File "C:\Users\chaoguog\Downloads\edx-platform-master\scripts\compile_sass.py", line 451, in <module> main(prog_name="npm run compile-sass --") File "C:\Users\chaoguog\Downloads\edx-platform-master\.venv\Lib\site-packages\click\core.py", line 1442, in __call__ return self.main(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\chaoguog\Downloads\edx-platform-master\.venv\Lib\site-packages\click\core.py", line 1363, in main rv = self.invoke(ctx) ^^^^^^^^^^^^^^^^ File "C:\Users\chaoguog\Downloads\edx-platform-master\.venv\Lib\site-packages\click\core.py", line 1226, in invoke return ctx.invoke(self.callback, **ctx.params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\chaoguog\Downloads\edx-platform-master\.venv\Lib\site-packages\click\core.py", line 794, in invoke return callback(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\chaoguog\Downloads\edx-platform-master\.venv\Lib\site-packages\click\decorators.py", line 34, in new_func return f(get_current_context(), *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\chaoguog\Downloads\edx-platform-master\scripts\compile_sass.py", line 335, in main compile_sass_dir( File "C:\Users\chaoguog\Downloads\edx-platform-master\scripts\compile_sass.py", line 252, in compile_sass_dir raise Exception(f"Failed to compile {source}: {output_text}") Exception: Failed to compile lms\static\sass\lms-main-v1-rtl.scss: Error: File to import not found or unreadable: mixins Parent style sheet: C:/Users/chaoguog/Downloads/edx-platform-master/lms/static/sass/_build-lms-v1.scss on line 81 of lms/static/sass/_build-lms-v1.scss >> @import &#39;mixins&#39;; ^
09-25
cmake --build . --target help The following are some of the valid targets for this Makefile: ... all (the default if no target is provided) ... clean ... depend ... edit_cache ... install ... install/local ... install/strip ... list_install_components ... rebuild_cache ... test ... Continuous ... ContinuousBuild ... ContinuousConfigure ... ContinuousCoverage ... ContinuousMemCheck ... ContinuousStart ... ContinuousSubmit ... ContinuousTest ... ContinuousUpdate ... Experimental ... ExperimentalBuild ... ExperimentalConfigure ... ExperimentalCoverage ... ExperimentalMemCheck ... ExperimentalStart ... ExperimentalSubmit ... ExperimentalTest ... ExperimentalUpdate ... Nightly ... NightlyBuild ... NightlyConfigure ... NightlyCoverage ... NightlyMemCheck ... NightlyMemoryCheck ... NightlyStart ... NightlySubmit ... NightlyTest ... NightlyUpdate ... build_info ... common ... ggml ... ggml-base ... ggml-cpu ... llama ... llama-batched ... llama-batched-bench ... llama-bench ... llama-cli ... llama-convert-llama2c-to-ggml ... llama-cvector-generator ... llama-diffusion-cli ... llama-embedding ... llama-eval-callback ... llama-export-lora ... llama-finetune ... llama-gemma3-cli ... llama-gen-docs ... llama-gguf ... llama-gguf-hash ... llama-gguf-split ... llama-imatrix ... llama-llava-cli ... llama-logits ... llama-lookahead ... llama-lookup ... llama-lookup-create ... llama-lookup-merge ... llama-lookup-stats ... llama-minicpmv-cli ... llama-mtmd-cli ... llama-parallel ... llama-passkey ... llama-perplexity ... llama-q8dot ... llama-quantize ... llama-qwen2vl-cli ... llama-retrieval ... llama-run ... llama-save-load-state ... llama-server ... llama-simple ... llama-simple-chat ... llama-speculative ... llama-speculative-simple ... llama-tokenize ... llama-tts ... llama-vdot ... mtmd ... sha1 ... sha256 ... test-alloc ... test-arg-parser ... test-autorelease ... test-backend-ops ... test-barrier ... test-c ... test-chat ... test-chat-parser ... test-chat-template ... test-gbnf-validator ... test-gguf ... test-grammar-integration ... test-grammar-parser ... test-json-partial ... test-json-schema-to-grammar ... test-llama-grammar ... test-log ... test-model-load-cancel ... test-mtmd-c-api ... test-opt ... test-quantize-fns ... test-quantize-perf ... test-quantize-stats ... test-regex-partial ... test-rope ... test-sampling ... test-thread-safety ... test-tokenizer-0 ... test-tokenizer-1-bpe ... test-tokenizer-1-spm ... xxhash
最新发布
10-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值