mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: Native theme support
This feature introduces the concept of themes. Themes are an evolution
of site customizations.
Themes introduce two very big conceptual changes:
- A theme may include other "child themes", children can include grand
children and so on.
- A theme may specify a color scheme
The change does away with the idea of "enabled" color schemes.
It also adds a bunch of big niceties like
- You can source a theme from a git repo
- History for themes is much improved
- You can only have a single enabled theme. Themes can be selected by
users, if you opt for it.
On a technical level this change comes with a whole bunch of goodies
- All CSS is now compiled using a custom pipeline that uses libsass
see /lib/stylesheet
- There is a single pipeline for css compilation (in the past we used
one for customizations and another one for the rest of the app
- The stylesheet pipeline is now divorced of sprockets, there is no
reliance on sprockets for CSS bundling
- CSS is generated with source maps everywhere (including themes) this
makes debugging much easier
- Our "live reloader" is smarter and avoid a flash of unstyled content
we run a file watcher in "puma" in dev so you no longer need to run
rake autospec to watch for CSS changes
This commit is contained in:
85
app/models/remote_theme.rb
Normal file
85
app/models/remote_theme.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
require_dependency 'git_importer'
|
||||
|
||||
class RemoteTheme < ActiveRecord::Base
|
||||
has_one :theme
|
||||
|
||||
def self.import_theme(url, user=Discourse.system_user)
|
||||
importer = GitImporter.new(url)
|
||||
importer.import!
|
||||
|
||||
theme_info = JSON.parse(importer["about.json"])
|
||||
theme = Theme.new(user_id: user&.id || -1, name: theme_info["name"])
|
||||
|
||||
remote_theme = new
|
||||
theme.remote_theme = remote_theme
|
||||
|
||||
remote_theme.remote_url = importer.url
|
||||
remote_theme.update_from_remote(importer)
|
||||
|
||||
theme.save!
|
||||
theme
|
||||
ensure
|
||||
begin
|
||||
importer.cleanup!
|
||||
rescue => e
|
||||
Rails.logger.warn("Failed cleanup remote git #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def update_remote_version
|
||||
importer = GitImporter.new(remote_url)
|
||||
importer.import!
|
||||
self.updated_at = Time.zone.now
|
||||
self.remote_version, self.commits_behind = importer.commits_since(remote_version)
|
||||
end
|
||||
|
||||
def update_from_remote(importer=nil)
|
||||
return unless remote_url
|
||||
cleanup = false
|
||||
unless importer
|
||||
cleanup = true
|
||||
importer = GitImporter.new(remote_url)
|
||||
importer.import!
|
||||
end
|
||||
|
||||
Theme.targets.keys.each do |target|
|
||||
Theme::ALLOWED_FIELDS.each do |field|
|
||||
value = importer["#{target}/#{field=="scss"?"#{target}.scss":"#{field}.html"}"]
|
||||
theme.set_field(target.to_sym, field, value)
|
||||
end
|
||||
end
|
||||
|
||||
theme_info = JSON.parse(importer["about.json"])
|
||||
self.license_url ||= theme_info["license_url"]
|
||||
self.about_url ||= theme_info["about_url"]
|
||||
|
||||
self.remote_updated_at = Time.zone.now
|
||||
self.remote_version = importer.version
|
||||
self.local_version = importer.version
|
||||
self.commits_behind = 0
|
||||
|
||||
self
|
||||
ensure
|
||||
begin
|
||||
importer.cleanup! if cleanup
|
||||
rescue => e
|
||||
Rails.logger.warn("Failed cleanup remote git #{e}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: remote_themes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# remote_url :string not null
|
||||
# remote_version :string
|
||||
# local_version :string
|
||||
# about_url :string
|
||||
# license_url :string
|
||||
# commits_behind :integer
|
||||
# remote_updated_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
#
|
||||
Reference in New Issue
Block a user