Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[frontend/theme] script for bootswatch theme compilation #931

Open
wants to merge 56 commits into
base: master
Choose a base branch
from

Conversation

Ananas120
Copy link

Script to compile (new) bootswatch theme

Usage :

  • Go to inginious/frontend/static/css/themes
  • Run make yeti to compile the yeti theme

@CLAassistant
Copy link

CLAassistant commented Apr 3, 2023

CLA assistant check
All committers have signed the CLA.

Copy link
Member

@anthonygego anthonygego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the source files should be present so that at least the devs can rebuild the themes. We agreed previously to keep a submodule of bootswatch to be sure we are using a version compatible with our sources. It's probably also possible to keep the all process done by grunt only not to add additional development dependencies.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the compiled version. The source file should be stored somewhere.

mv bootswatch/dist/$(theme)/bootstrap.css $(theme).css

install:
git clone $BOOTSWATCH_URL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case we do not use a fixed version as discussed before. @nrybowski suggested to use a submodule to include the source at a given commit stage. We can probably add a third-party folder at the source root to store the submodule.

Besides, as discussed previously, it would probably be better to store the source files for yeti and the modified yeti dark mode into our repository (keeping their copyright of course) and only keep a submodule to bootstrap.

In all case we need to be able to rebuild the dark_mode.css file from the sources.

BASE_THEME = yeti

compile:
if [ ! -d "bootswatch" ]; then make install; fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more convenient if all these steps could be carried out by grunt to avoid adding development dependencies. In case the yeti sources are provided in our repo the build configuration file should be provided too and can be modified to place the file in the appropriate locations.

@@ -21,7 +21,7 @@
<!-- INGInious Style -->
<link href="{{get_homepath(True)}}/static/css/INGInious-rtl.css?v2" rel="stylesheet">
{% else %}
<link href="{{get_homepath(True)}}/static/css/bootstrap.min.css" rel="stylesheet">
<link href="{{get_homepath(True)}}/static/css/themes/default.min.css" rel="stylesheet">
<!-- INGInious Style -->
<link href="{{get_homepath(True)}}/static/css/INGInious.css?v2" rel="stylesheet">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should also provide a specific version of this file for the different themes ?

@Ananas120
Copy link
Author

I have updated the workflow to remove the need of any third-party module by copying the Gruntfile + build directory from the bootswatch repo (which is enough for theme compilation)
I have also added the "darkly" theme with the "dracula" CodeMirror theme (not fully tested in inginious + theme not deployable yet)

I left the Makefile for simplicty but it is not required

Copy link
Member

@anthonygego anthonygego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made comments based on reading the code only. Please fetch the files for Bootstrap 4 in the base repo first.

"devDependencies": {
"@lodder/grunt-postcss": "^3.1.1",
"autoprefixer": "^10.4.12",
"bootstrap": "^5.2.3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current codebase still relies on Bootstrap 4. This is probably the first change to do (the first comment to treat).

const autoprefixer = require('autoprefixer');
const pkg = require('./package.json');

const SWATCHES = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably be cleaned

@@ -0,0 +1,125 @@
<!DOCTYPE html>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need to keep any thumbnail rendering feature. I guess ?

themes/test.html Outdated
@@ -0,0 +1,12 @@
<!DOCTYPE html>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test file should not be pushed into the repository

@@ -0,0 +1,266 @@
'use strict';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep a note here about the original author.


const BUILD_DIR = 'build/';
const DIST_DIR = 'themes/';
const DOCS_DEST = 'docs/5/';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can delete all things related to docs as we don't aim at redistributing a full modified bootstrap copy.

.gitignore Outdated
@@ -23,7 +23,12 @@ venv
inginious/tasks
# Default backup directory
inginious/backup
# The themes files
themes/node_modules
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The themes folder can be put into the frontend one. This would make sense.

themes/Makefile Outdated
OUTPUT_DIR = ../inginious/frontend/static/css/themes

compile:
if [ ! -d "node_modules" ]; then make install; fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually don't ask this to be modified, but make supports dependencies handling. That's one of his core features.

themes/Makefile Outdated
if [ ! -d "node_modules" ]; then make install; fi
if [ ! -d "$(OUTPUT_DIR)/$(theme)" ]; then cp -r $(OUTPUT_DIR)/default $(OUTPUT_DIR)/$(theme); fi
./node_modules/grunt/bin/grunt swatch:$(theme)
mv $(THEMES_DIR)/$(theme)/bootstrap.min.css $(OUTPUT_DIR)/$(theme)/.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should clearly be way to modify Gruntfile.js in order to compile all themes as the default action, and to copy the bootstrap.min.css in the appropriate folder.

This way, this whole Makefile would be kind of useless and compiling the themes would just consists in npm install and grunt.

themes/Makefile Outdated

install:
npm install
npm install grunt-cli
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add grunt-cli as a dependency in package.json.

@Ananas120
Copy link
Author

Here is the updated version shown last week :

  • The makefile has been removed as well as the test.html and the docs/ folder
  • The Gruntfile has been cleaned up
  • The command to compile theme is the grunt build:<theme>
  • The themes/codemirror/ contains all available themes from https://codemirror.net/5/themes, and are properly integrated in inginious (at least in darkly and default (yeti) themes).
  • The INGInious.css file is specific to each theme as some coloring styles had to be removed for the darkly theme (it should be checked if these coloring styles are really relevant in the regular yeti theme)
  • The _bootswatch.scss file from darkly has been modified to better fit high contrast (especially in the "warning" or "info" tags used multiple times in inginious buttons / side-bar)
  • The "profile.js" and "profile" page / logic and user_manager has been modified to add the color / codemirror-color themes the same way as the language. The list is automatically adapted according to the available themes in frontend/static/css/themes(/codemirror)
  • The "common.js" file has been modified to support "non-default" codemirror theme (by adding the "theme" key). The "Codemirror.colorize" method does not support custom theme, it is the reason why I have added the "replace(...)" line + a custom html tag "theme=..." to get the information on the codemirror-theme used.
  • The "codemirror/default.css" is an empty file as the default configuration (style) is already in "codemirror/main.css". However, this "main" file is required for all the codemirror themes, as the theme-specific files only defines coloring-styles (and not the other configurations).It is the reason why I have created a "default" empty file, such that it is automatically included in the available theme list (and it is empty as it does not overwrite the "main.css" default colors)

Copy link
Member

@anthonygego anthonygego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think you can split this PR in :

  • One with the themes and inginious/frontend/static/css changes. (that is, essentially the imported files and building logic)
  • One with the remaining changes (that is, the effective integration into INGInious)

That would allow me to make sure my review is complete as I don't want to review all the imported CSS files, the review listing is a bit messy right now :-)

Do not delete this one now

@@ -175,6 +175,15 @@ def get_app(config):
available_languages = {"en": "English"}
available_languages.update(available_translations)

available_themes = [
theme_dir for theme_dir in os.listdir(os.path.join('inginious', 'frontend', 'static', 'css', 'themes'))
if theme_dir not in ('yeti', 'codemirror') and not theme_dir.startswith(('.', '_'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure yeti is required as an exception here.

@@ -175,6 +175,15 @@ def get_app(config):
available_languages = {"en": "English"}
available_languages.update(available_translations)

available_themes = [
theme_dir for theme_dir in os.listdir(os.path.join('inginious', 'frontend', 'static', 'css', 'themes'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use inginious.get_root_path() here. This will avoid issues with the current working directory environment variable. Typically in a production setup where the inginious-webapp script is not in the same directory as the inginious package.

if theme_dir not in ('yeti', 'codemirror') and not theme_dir.startswith(('.', '_'))
]
available_codemirror_themes= [
file.split('.')[0] for file in os.listdir(os.path.join('inginious', 'frontend', 'static', 'css', 'themes', 'codemirror'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here for the path.

@@ -35,6 +35,8 @@ def run(self):
if not self.content:
translation = _get_inginious_translation()
self.content = [translation.gettext("[no content]")]

self.options.setdefault('classes', []).append('theme={}'.format(flask.current_app.user_manager.get_codemirror_theme()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be OK but maybe it's more careful and idiomatic (it seems to be the de-facto rule) to use - instead of = to separate the prefix of your CSS class.

In case of bad HTML, browsers typically try to fix the error by themselves. A = is part of the HTML tag syntax and may be badly interpreted as an attribute in case a correction is needed. Of course we aim at providing valid HTML to the client, but those things can still happen.

mode = nmode;
} else if (elem.startsWith('theme=')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... continuation of my comment about -and =.

@@ -33,6 +33,14 @@ class AuthInvalidMethodException(Exception):

class AuthMethod(object, metaclass=ABCMeta):

@abstractmethod
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those methods do not have to be defined in AuthMethod class as there should be no dependance between them.

@@ -107,6 +115,12 @@ def sanitize_email(cls, email: str) -> str:
# User session management #
##############################################

def get_theme(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather call them session_theme and session_codemirror_theme to use the same nomenclature and recall throughout the code that those values are fetched from the user session.

@@ -7,6 +7,7 @@

<textarea name="{{inputId}}"
class="code-editor form-control {% if '/' in inputId %} single {% endif %}"
theme="dracula"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded value :-)

@@ -0,0 +1,170 @@
'use strict';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can rename themes/themes into themes/src to be less confusing.

You should probably add an initial comment such as

Based on Bootswatch from Thomas Park (https://github.com/thomaspark/bootswatch)

in the beginning of the imported files

@Ananas120
Copy link
Author

I still update this branch PR to be sure, I will now try to create a new one on the tasksets branch...

@Ananas120
Copy link
Author

All the commands you told me have (in theory) been successfully executed, and conflicts solved ! Hope it is correct now
Note that for the "theme=" comment, I have changed to "theme:" instead of "theme-" because some codemirror themes have the "-" symbol, which may raise errors when splitting it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants