Skip to content

Commit e07017a

Browse files
authored
Merge pull request #18 from aamirbhat/develop
Develop
2 parents 7715a63 + a2f29fd commit e07017a

File tree

10 files changed

+194
-162
lines changed

10 files changed

+194
-162
lines changed

README.md

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ STATICFILES_DIRS = (
6767
'DEFAULT': {
6868
'BUNDLE_DIR_NAME': REACT_BUILD_DIRECTORY,
6969
'FRONT_END_SERVER': "http://localhost:3000/",
70-
'is_dev': False,
70+
'IS_DEV': False,
7171
}
7272
}
7373
```
@@ -96,14 +96,16 @@ STATICFILES_DIRS = (
9696
9797
CREATE_REACT_APP = {
9898
'DEFAULT': {
99-
'BUNDLE_DIR_NAME': CLIENT_FRONTEND_BUILD,
99+
'BUNDLE_DIR_NAME': REACT_BUILD,
100100
'FRONT_END_SERVER': "http://localhost:3000/",
101-
'is_dev': True,
102-
},
101+
'IS_DEV': False,
102+
"PUBLIC_PATH_DEV": "http://localhost:3000/",
103+
"PUBLIC_PATH": "/static/"
104+
}
103105
'ADMIN': {
104-
'BUNDLE_DIR_NAME': ADMIN_FRONTEND_BUILD,
105-
'FRONT_END_SERVER': "http://localhost:3001/",
106-
'is_dev': True,
106+
'BUNDLE_DIR_NAME': REACT_BUILD,
107+
'FRONT_END_SERVER': "http://localhost:3000/",
108+
'IS_DEV': False,
107109
},
108110
}
109111
@@ -113,6 +115,9 @@ make sure react app is running on FRONT_END_SERVER on same port which is declare
113115
#### is_dev: False
114116
make sure build path is pointed to the right build directory
115117

118+
119+
120+
116121
### Rendering react admin app inside templates ::
117122
```
118123
{% load react_bundle_loader %}
@@ -128,3 +133,37 @@ make sure build path is pointed to the right build directory
128133
</head>
129134
130135
```
136+
137+
138+
### Using Preloading ::
139+
The is_preload=True option in the render_bundle_css or render_bundle_js template tag can be used to add rel="preload" link tags.
140+
```
141+
{% render_bundle_css is_preload=True %}
142+
143+
```
144+
145+
### Add attributes
146+
add some extra attributes to the tag
147+
```
148+
{% render_bundle_js attrib="async" %}
149+
150+
{% render_bundle_js attrib="disabled" %}
151+
```
152+
153+
154+
### migration from 0.8.4 to 0.9
155+
"is_dev" changed to "IS_DEV"
156+
is_dev in lowercase will not work
157+
158+
159+
### docker support
160+
PUBLIC_PATH_DEV default value will be FRONT_END_SERVER, which will be used for incase of docker
161+
162+
PUBLIC_PATH_DEV will be used in case of docker to http://localhost:3000/
163+
FRONT_END_SERVER: host.docker.internal
164+
165+
### django storage support
166+
167+
change PUBLIC_PATH to storagepath e.g
168+
169+
PUBLIC_PATH:"https://234234234.aws.com/static/"

create_react_app/asset.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from create_react_app.config import get_loader
2+
from create_react_app.utils import _filter_by_extension
3+
4+
5+
class AssetTag:
6+
def __init__(self, public_path):
7+
self.public_path = public_path
8+
9+
def css_tag(self, asset_path, attrib="", is_preload=False):
10+
if is_preload:
11+
return '<link rel="preload" href="{0}{1}" {2} as="style" />'.format(self.public_path, asset_path, attrib)
12+
return '<link type="text/css" href="{0}{1}" rel="stylesheet" {2}/>'.format(self.public_path, asset_path, attrib)
13+
14+
def script_tag(self, asset_path, attrib="", is_preload=False):
15+
if is_preload:
16+
return '<link rel="preload" href="{0}{1}" {2} as="script" />'.format(self.public_path, asset_path, attrib)
17+
return '<script type="text/javascript" src="{0}{1}" {2}></script>'.format(self.public_path, asset_path, attrib)
18+
19+
def src(self, asset_path, **extra):
20+
return '{0}{1}'.format(self.public_path, asset_path)
21+
22+
23+
class AssetManager(object):
24+
def __init__(self, config_name):
25+
self.loader = get_loader(config_name)
26+
self.asset = AssetTag(self.loader.asset_path)
27+
28+
def get_bundle(self, extension):
29+
bundle = self.loader.get_bundle()
30+
if extension:
31+
bundle = _filter_by_extension(bundle, extension)
32+
if not bundle:
33+
return []
34+
return bundle
35+
36+
def get_tag_bundle(self, extension, call_back, ends_with=[], **extra):
37+
tags = []
38+
bundle = self.get_bundle(extension=extension)
39+
for chunk in bundle:
40+
if not self.loader.is_dev:
41+
chunk = chunk.replace("static/", "")
42+
if chunk.endswith(tuple(ends_with)):
43+
tags.append(call_back(chunk, **extra))
44+
return tags
45+
46+
def css_callback(self, chunk, **extra):
47+
return self.asset.css_tag(chunk, **extra)
48+
49+
def js_callback(self, chunk, **extra):
50+
return self.asset.script_tag(chunk, **extra)
51+
52+
def css_tags(self, **extra):
53+
return self.get_tag_bundle(extension="css", call_back=self.css_callback, ends_with=['.css', '.css.gz'], **extra)
54+
55+
def js_tags(self, **extra):
56+
return self.get_tag_bundle(extension="js", call_back=self.js_callback, ends_with=['.js', '.js.gz'], **extra)
57+
58+
59+
class SrcAssetManager(AssetManager):
60+
def js_callback(self, chunk, **extra):
61+
return self.asset.src(chunk, **extra)
62+
63+
def css_callback(self, chunk, **extra):
64+
return self.asset.src(chunk, **extra)

create_react_app/config.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
import re
22

33
from django.conf import settings
4+
from importlib import import_module
45

56
__all__ = ('load_config',)
67

8+
_loaders = {}
9+
ASSET_LOADER_CACHE = getattr(settings, "RUNTIME_ASSET_LOADER", False)
10+
711
DEFAULT_CONFIG = {
812
'DEFAULT': {
913
'CACHE': True,
1014
'BUNDLE_DIR_NAME': '/Users/aamirbhatt/workspace/hack_django_react/dashboard/static',
1115
'LOADER_CLASS': 'create_react_app.loader.CreateReactLoader',
1216
'FRONT_END_SERVER': "http://localhost:3000/",
13-
'is_dev': False,
17+
'PUBLIC_PATH': "/static/",
18+
"PUBLIC_PATH_DEV": "/",
19+
'IS_DEV': False
1420
}
1521
}
1622

@@ -24,3 +30,25 @@
2430

2531
def load_config(name):
2632
return user_config[name]
33+
34+
35+
def import_string(dotted_path):
36+
'''
37+
This is a rough copy of django's import_string, which wasn't introduced until Django 1.7
38+
Once this package's support for Django 1.6 has been removed, this can be safely replaced with
39+
`from django.utils.module_loading import import_string`
40+
'''
41+
try:
42+
module_path, class_name = dotted_path.rsplit('.', 1)
43+
module = import_module(module_path)
44+
return getattr(module, class_name)
45+
except (ValueError, AttributeError, ImportError):
46+
raise ImportError('%s doesn\'t look like a valid module path' % dotted_path)
47+
48+
49+
def get_loader(config_name, manifest_path=None):
50+
if config_name not in _loaders or ASSET_LOADER_CACHE:
51+
config = load_config(config_name)
52+
loader_class = import_string(config['LOADER_CLASS'])
53+
_loaders[config_name] = loader_class(config, manifest_path)
54+
return _loaders[config_name]

create_react_app/loader.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import json
22
import os
3-
import time
43
from io import open
54

6-
from django.conf import settings
7-
from django.contrib.staticfiles.storage import staticfiles_storage
85

96
from .exception import (
107
WebpackError,
@@ -21,17 +18,34 @@ class CreateReactLoader(object):
2118

2219
def __init__(self, config, manifest_path=None):
2320
self.config = config
24-
self.is_dev = self.config.get("is_dev", False)
25-
self.manifest_path = manifest_path
21+
self.manifest_file_path = manifest_path
22+
23+
@property
24+
def is_dev(self):
25+
return self.config.get("IS_DEV", False)
26+
27+
def get_dev_path(self):
28+
dev_asset_path = self.config['FRONT_END_SERVER']
29+
public_path_dev = self.config.get("PUBLIC_PATH_DEV")
30+
if public_path_dev != "/":
31+
dev_asset_path = public_path_dev
32+
33+
return dev_asset_path.strip('/') + "/"
2634

2735
@property
2836
def asset_path(self):
37+
public_path = self.config.get("PUBLIC_PATH")
2938
if self.is_dev:
30-
return self.config['FRONT_END_SERVER'].strip('/') + "/"
31-
return "/"
39+
return self.get_dev_path()
40+
return public_path
41+
42+
@property
43+
def manifest_path(self):
44+
dev_asset_path = self.config['FRONT_END_SERVER']
45+
return dev_asset_path.strip('/') + "/"
3246

3347
def get_dev_assets(self):
34-
server = self.asset_path
48+
server = self.manifest_path
3549
url = "{frontend_server}{asset_file}".format(frontend_server=server, asset_file=self.asset_file)
3650
try:
3751
data = requests.get(url, timeout=3)
@@ -44,8 +58,8 @@ def get_dev_assets(self):
4458
def get_prod_assets(self):
4559
try:
4660
build_folder = self.config['BUNDLE_DIR_NAME']
47-
if self.manifest_path:
48-
manifest_file = self.manifest_path
61+
if self.manifest_file_path:
62+
manifest_file = self.manifest_file_path
4963
else:
5064
manifest_file = os.path.join(build_folder, self.asset_file)
5165
with open(manifest_file, encoding="utf-8") as f:
@@ -56,7 +70,7 @@ def get_prod_assets(self):
5670
'the asset-manifest file in the build directory and the path is correct?')
5771

5872
def get_assets(self):
59-
if self.is_dev and not self.manifest_path:
73+
if self.is_dev and not self.manifest_file_path:
6074
return self.get_dev_assets()
6175
return self.get_prod_assets()
6276

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,29 @@
11
from django import template
22
from django.utils.safestring import mark_safe
3-
4-
from .. import utils
3+
from ..asset import AssetManager, SrcAssetManager
54

65
register = template.Library()
76

87

98
@register.simple_tag
10-
def render_bundle_css(config="DEFAULT"):
11-
tags = utils.get_as_tags(extension='css', config=config)
9+
def render_bundle_css(config="DEFAULT", is_preload=False, attrib=''):
10+
tags = AssetManager(config).css_tags(is_preload=is_preload, attrib=attrib)
1211
return mark_safe('\n'.join(tags))
1312

1413

1514
@register.simple_tag
16-
def render_bundle_js(config="DEFAULT"):
17-
tags = utils.get_as_tags(extension='js', config=config)
15+
def render_bundle_js(config="DEFAULT", is_preload=False, attrib=''):
16+
tags = AssetManager(config).js_tags(is_preload=is_preload, attrib=attrib)
1817
return mark_safe('\n'.join(tags))
1918

19+
2020
@register.simple_tag
2121
def render_bundle_src_css(config="DEFAULT"):
22-
tags = utils.get_src_files(extension='css', config=config)
22+
tags = SrcAssetManager(config).css_tags()
2323
return tags
2424

2525

2626
@register.simple_tag
2727
def render_bundle_src_js(config="DEFAULT"):
28-
tags = utils.get_as_tags(extension='js', config=config)
28+
tags = SrcAssetManager(config).js_tags()
2929
return tags
30-
31-
32-
@register.simple_tag
33-
def render_bundle_page_css(page_name="main", config="DEFAULT"):
34-
tags = utils.get_tags_per_page(extension='css', page_name=page_name, config=config)
35-
return mark_safe('\n'.join(tags))
36-
37-
38-
@register.simple_tag
39-
def render_bundle_page_js(page_name="main", config="DEFAULT"):
40-
tags = utils.get_tags_per_page(extension='js', page_name=page_name, config=config)
41-
return mark_safe('\n'.join(tags))
42-
43-
@register.simple_tag
44-
def render_asset_page_css(page_name="main", manifest_path=None):
45-
tags = utils.get_tags_per_page(extension='css', page_name=page_name, manifest_path=manifest_path)
46-
return mark_safe('\n'.join(tags))
47-
48-
49-
@register.simple_tag
50-
def render_asset_page_js(page_name="main", manifest_path=None):
51-
tags = utils.get_tags_per_page(extension='js', page_name=page_name, manifest_path=manifest_path)
52-
return mark_safe('\n'.join(tags))
53-
54-
55-
56-
@register.simple_tag
57-
def render_bundle_page_src_css(page_name="main", config="DEFAULT"):
58-
tags = utils.get_src_files(extension='css', page_name=page_name, config=config)
59-
return mark_safe('\n'.join(tags))
60-
61-
62-
@register.simple_tag
63-
def render_bundle_page_src_js(page_name="main", config="DEFAULT"):
64-
tags = utils.get_src_files(extension='js', page_name=page_name, config=config)
65-
return mark_safe('\n'.join(tags))

0 commit comments

Comments
 (0)