diff options
30 files changed, 2624 insertions, 1288 deletions
diff --git a/forum/management/__init__.py b/forum/management/__init__.py index e69de29b..8266592a 100644 --- a/forum/management/__init__.py +++ b/forum/management/__init__.py @@ -0,0 +1,3 @@ +from forum.modules import get_modules_script
+
+get_modules_script('management')
\ No newline at end of file diff --git a/forum/models/__init__.py b/forum/models/__init__.py index 2ab7b263..ccc53a7c 100755 --- a/forum/models/__init__.py +++ b/forum/models/__init__.py @@ -38,11 +38,13 @@ User.add_to_class('email_isvalid', models.BooleanField(default=False)) User.add_to_class('email_key', models.CharField(max_length=32, null=True))
User.add_to_class('reputation', models.PositiveIntegerField(default=1))
User.add_to_class('gravatar', models.CharField(max_length=32))
-User.add_to_class('favorite_questions',
- models.ManyToManyField(Question, through=FavoriteQuestion,
- related_name='favorited_by'))
-User.add_to_class('badges', models.ManyToManyField(Badge, through=Award,
- related_name='awarded_to'))
+
+#User.add_to_class('favorite_questions',
+# models.ManyToManyField(Question, through=FavoriteQuestion,
+# related_name='favorited_by'))
+
+#User.add_to_class('badges', models.ManyToManyField(Badge, through=Award,
+# related_name='awarded_to'))
User.add_to_class('gold', models.SmallIntegerField(default=0))
User.add_to_class('silver', models.SmallIntegerField(default=0))
User.add_to_class('bronze', models.SmallIntegerField(default=0))
@@ -326,4 +328,14 @@ __all__ = [ 'Activity',
'EmailFeedSetting',
'AnonymousEmail',
+
+ 'User'
]
+
+
+from forum.modules import get_modules_script_classes
+
+for k, v in get_modules_script_classes('models', models.Model).items():
+ if not k in __all__:
+ __all__.append(k)
+ exec "%s = v" % k
\ No newline at end of file diff --git a/forum/models/question.py b/forum/models/question.py index 20779d26..27d6e9d9 100755 --- a/forum/models/question.py +++ b/forum/models/question.py @@ -129,6 +129,8 @@ class Question(Content, DeletableContent): tagnames = models.CharField(max_length=125)
summary = models.CharField(max_length=180)
+ favorited_by = models.ManyToManyField(User, through='FavoriteQuestion', related_name='favorite_questions')
+
objects = QuestionManager()
class Meta(Content.Meta):
@@ -283,7 +285,7 @@ class FavoriteQuestion(models.Model): """A favorite Question of a User."""
question = models.ForeignKey(Question)
user = models.ForeignKey(User, related_name='user_favorite_questions')
- added_at = models.DateTimeField(default=datetime.datetime.now)
+ added_at = models.DateTimeField(default=datetime.datetime.now)
class Meta:
app_label = 'forum'
diff --git a/forum/models/repute.py b/forum/models/repute.py index 768dbee6..cac761da 100755 --- a/forum/models/repute.py +++ b/forum/models/repute.py @@ -21,6 +21,8 @@ class Badge(models.Model): # Denormalised data
awarded_count = models.PositiveIntegerField(default=0)
+ awarded_to = models.ManyToManyField(User, through='Award', related_name='badges')
+
class Meta:
app_label = 'forum'
db_table = u'badge'
diff --git a/forum/modules.py b/forum/modules.py new file mode 100755 index 00000000..53cc619a --- /dev/null +++ b/forum/modules.py @@ -0,0 +1,54 @@ +import os
+import types
+
+MODULES_PACKAGE = 'forum_modules'
+
+MODULES_FOLDER = os.path.join(os.path.dirname(__file__), '../' + MODULES_PACKAGE)
+
+MODULE_LIST = [
+ __import__('forum_modules.%s' % f, globals(), locals(), ['forum_modules'])
+ for f in os.listdir(MODULES_FOLDER)
+ if os.path.isdir(os.path.join(MODULES_FOLDER, f)) and
+ os.path.exists(os.path.join(MODULES_FOLDER, "%s/__init__.py" % f)) and
+ not os.path.exists(os.path.join(MODULES_FOLDER, "%s/DISABLED" % f))
+]
+
+def get_modules_script(script_name):
+ all = []
+
+ for m in MODULE_LIST:
+ try:
+ all.append(__import__('%s.%s' % (m.__name__, script_name), globals(), locals(), [m.__name__]))
+ except:
+ pass
+
+ return all
+
+def get_modules_script_classes(script_name, base_class):
+ scripts = get_modules_script(script_name)
+ all_classes = {}
+
+ for script in scripts:
+ all_classes.update(dict([
+ (n, c) for (n, c) in [(n, getattr(script, n)) for n in dir(script)]
+ if isinstance(c, (type, types.ClassType)) and issubclass(c, base_class)
+ ]))
+
+ return all_classes
+
+def get_all_handlers(name):
+ handler_files = get_modules_script('handlers')
+
+ return [
+ h for h in [
+ getattr(f, name) for f in handler_files
+ if hasattr(f, name)
+ ]
+
+ if callable(h)
+ ]
+
+def get_handler(name, default):
+ all = get_all_handlers(name)
+ print(len(all))
+ return len(all) and all[0] or default
\ No newline at end of file diff --git a/forum/skins/default/media/style/style.css b/forum/skins/default/media/style/style.css index 175fcb66..02148ab0 100644 --- a/forum/skins/default/media/style/style.css +++ b/forum/skins/default/media/style/style.css @@ -1,656 +1,1340 @@ @import url(jquery.autocomplete.css); @import url(openid.css); @import url(prettify.css); + /* 公用 */ -body{background:#FFF; font-size:12px; line-height:150%; margin:0; padding:0; color:#000; font-family: sans-serif; -} -div{margin:0 auto; padding:0;} -h1,h2,h3,h4,h5,h6,ul,li,dl,dt,dd,form,img,p{margin:0; padding:0; border:none; } -label {vertical-align:middle;} -hr {border:none;border-top: 1px dashed #ccccce;} -input, select {vertical-align:middle;font-family:Trebuchet MS,"segoe ui",Helvetica,"Microsoft YaHei",宋体,Tahoma,Verdana,MingLiu,PMingLiu,Arial,sans-serif;} -p{margin-bottom:13px; font-size:13px; line-height:140%;} -a {color:#333333; text-decoration:none;} -.badges a {color:#763333;text-decoration:underline;} -a:hover {text-decoration:underline;} -.block{width:960px; height:auto;} -.fleft{float:left;} -.fright{float:right;} -.tleft{text-align:left;} -.tcenter{text-align:center;} -.tright{text-align:right;} -.dis{display:block;} -.inline{display:inline;} -.none{display:none;} -.red{color:#CC0000;} -.b{font-weight:bold;} -.f10{font-size:10px;} -.f11{font-size:11px;} -.f12{font-size:12px;} -.f13{font-size:13px;} -.f14{font-size:14px;} -.white{color:#FFFFFF;} -.u{text-decoration:underline;} -.spacer1{height:6px; line-height:6px; clear:both; visibility:hidden;} -.spacer3{height:30px; line-height:30px; clear:both; visibility:hidden;} -h1{font-size:160%;padding:5px 0 5px 0;} -h2{font-size:140%;padding:3px 0 3px 0;} -h3{font-size:120%;padding:3px 0 3px 0;} -ul -{ - list-style: disc; - margin-left: 20px; - padding-left:0px; - margin-bottom: 1em; -} -ol -{ - list-style: decimal; - margin-left: 30px; - margin-bottom: 1em; - padding-left:0px; +body { + background: #FFF; + font-size: 12px; + line-height: 150%; + margin: 0; + padding: 0; + color: #000; + font-family: sans-serif; +} + +div { + margin: 0 auto; + padding: 0; +} + +h1, h2, h3, h4, h5, h6, ul, li, dl, dt, dd, form, img, p { + margin: 0; + padding: 0; + border: none; +} + +label { + vertical-align: middle; +} + +hr { + border: none; + border-top: 1px dashed #ccccce; +} + +input, select { + vertical-align: middle; + font-family: Trebuchet MS, "segoe ui", Helvetica, "Microsoft YaHei", 宋 体, Tahoma, Verdana, MingLiu, PMingLiu, Arial, sans-serif; +} + +p { + margin-bottom: 13px; + font-size: 13px; + line-height: 140%; +} + +a { + color: #333333; + text-decoration: none; +} + +.badges a { + color: #763333; + text-decoration: underline; +} + +a:hover { + text-decoration: underline; +} + +.block { + width: 960px; + height: auto; +} + +.fleft { + float: left; +} + +.fright { + float: right; +} + +.tleft { + text-align: left; +} + +.tcenter { + text-align: center; +} + +.tright { + text-align: right; +} + +.dis { + display: block; +} + +.inline { + display: inline; +} + +.none { + display: none; } + +.red { + color: #CC0000; +} + +.b { + font-weight: bold; +} + +.f10 { + font-size: 10px; +} + +.f11 { + font-size: 11px; +} + +.f12 { + font-size: 12px; +} + +.f13 { + font-size: 13px; +} + +.f14 { + font-size: 14px; +} + +.white { + color: #FFFFFF; +} + +.u { + text-decoration: underline; +} + +.spacer1 { + height: 6px; + line-height: 6px; + clear: both; + visibility: hidden; +} + +.spacer3 { + height: 30px; + line-height: 30px; + clear: both; + visibility: hidden; +} + +h1 { + font-size: 160%; + padding: 5px 0 5px 0; +} + +h2 { + font-size: 140%; + padding: 3px 0 3px 0; +} + +h3 { + font-size: 120%; + padding: 3px 0 3px 0; +} + +ul { + list-style: disc; + margin-left: 20px; + padding-left: 0px; + margin-bottom: 1em; +} + +ol { + list-style: decimal; + margin-left: 30px; + margin-bottom: 1em; + padding-left: 0px; +} + td ul { - vertical-align:middle; + vertical-align: middle; } + li input { margin: 3px 3px 4px 3px; } -pre -{ - font-family: Consolas, Monaco, Liberation Mono, Lucida Console, Monospace; - font-size:100%; - margin-bottom: 10px; - overflow: auto; - width: 580px; - background-color: #F5F5F5; - padding-left:5px; - padding-top:5px; - padding-bottom: 20px !ie7; + +pre { + font-family: Consolas, Monaco, Liberation Mono, Lucida Console, Monospace; + font-size: 100%; + margin-bottom: 10px; + overflow: auto; + width: 580px; + background-color: #F5F5F5; + padding-left: 5px; + padding-top: 5px; + padding-bottom: 20px ! ie7; } -code{ +code { font-family: Consolas, Monaco, Liberation Mono, Lucida Console, Monospace; - font-size:100%; + font-size: 100%; } -blockquote -{ - margin-bottom: 10px; - margin-right: 15px; - padding: 10px 0px 1px 10px; - background-color: #F5F5F5; +blockquote { + margin-bottom: 10px; + margin-right: 15px; + padding: 10px 0px 1px 10px; + background-color: #F5F5F5; } /*页面布局*/ -#wrapper {width:960px;margin:auto;padding:0;} +#wrapper { + width: 960px; + margin: auto; + padding: 0; +} + #roof { - position:relative; - margin-top:0px; - background:#FFF; -} -#room {padding:10px 0 10px 0;background-color:#FFF;border-bottom:1px solid #777;} -#CALeft{width:710px; float:left; position:relative;} -#CARight{width:240px; float:right;} -#CAFull{float:left;padding:0 5px 0 5px;width:950px;} -#ground {width:100%;border-top:1px solid #000; padding-top:6px; padding-bottom:0px; text-align:center;background:#777;} + position: relative; + margin-top: 0px; + background: #FFF; +} + +#room { + padding: 10px 0 10px 0; + background-color: #FFF; + border-bottom: 1px solid #777; +} + +#CALeft { + width: 710px; + float: left; + position: relative; +} + +#CARight { + width: 240px; + float: right; +} + +#CAFull { + float: left; + padding: 0 5px 0 5px; + width: 950px; +} + +#ground { + width: 100%; + border-top: 1px solid #000; + padding-top: 6px; + padding-bottom: 0px; + text-align: center; + background: #777; +} + /*#licenseLogo {position:absolute;top:10px;right:10px;}*/ /*顶部及导航栏*/ #top { - position:absolute; - top:0px; - right:0px; - height:20px; - text-align:right; - padding:3px; - background-color:#ffffff; - width:500px; + position: absolute; + top: 0px; + right: 0px; + height: 20px; + text-align: right; + padding: 3px; + background-color: #ffffff; + width: 500px; } + /*#header {width:960px;}*/ -#top a {height:35px; text-align:right; - /*letter-spacing:1px; */ - margin-left:20px;text-decoration:underline; font-size:12px; color:#333333;} +#top a { + height: 35px; + text-align: right; /*letter-spacing:1px; */ + margin-left: 20px; + text-decoration: underline; + font-size: 12px; + color: #333333; +} + #logo { - padding: 5px 0px 0px 0px; -} -#navBar {float:clear;position:relative;display:block;width:960px;} -#navBar .nav {margin:20px 0px 0px 16px; - /*letter-spacing:1px; */ - } -#navBar .nav a {color:#333333; background-color:#fff0e0; - /*border-left: 1px solid #eeeeec; - border-right: 1px solid #babdb6; - border-top: 1px solid #eeeeec;*/ - border: 1px solid #888888; - border-bottom: none; - padding:0px 12px 3px 12px; height:25px; line-height:30px;margin-left:10px; font-size:14px; font-weight:400; text-decoration:none;display: block;float: left;} -#navBar .nav a:hover {text-decoration:underline} -#navBar .nav a.on {height:24px;line-height:28px; - border-bottom: 1px solid #a40000; - border-right:1px solid #820000; - border-top:1px solid #d40000; - border-left:1px solid #d40000; - /*background:#A31E39; */ - background:#a40000; - color:#FFF; font-weight:600; text-decoration:none} -#navBar .nav a.special {font-size:14px; color:#B02B2C; font-weight:bold; text-decoration:none; } -#navBar .nav a.special:hover {text-decoration:underline;} -#navBar .nav div.focus {float:right; padding-right:0px;} + padding: 5px 0px 0px 0px; +} + +#navBar { + float: clear; + position: relative; + display: block; + width: 960px; +} + +#navBar .nav { + margin: 20px 0px 0px 16px; /*letter-spacing:1px; */ +} + +#navBar .nav a { + color: #333333; + background-color: #fff0e0; + /*border-left: 1px solid #eeeeec; + border-right: 1px solid #babdb6; + border-top: 1px solid #eeeeec;*/ + border: 1px solid #888888; + border-bottom: none; + padding: 0px 12px 3px 12px; + height: 25px; + line-height: 30px; + margin-left: 10px; + font-size: 14px; + font-weight: 400; + text-decoration: none; + display: block; + float: left; +} + +#navBar .nav a:hover { + text-decoration: underline +} + +#navBar .nav a.on { + height: 24px; + line-height: 28px; + border-bottom: 1px solid #a40000; + border-right: 1px solid #820000; + border-top: 1px solid #d40000; + border-left: 1px solid #d40000; /*background:#A31E39; */ + background: #a40000; + color: #FFF; + font-weight: 600; + text-decoration: none +} + +#navBar .nav a.special { + font-size: 14px; + color: #B02B2C; + font-weight: bold; + text-decoration: none; +} + +#navBar .nav a.special:hover { + text-decoration: underline; +} + +#navBar .nav div.focus { + float: right; + padding-right: 0px; +} + /*搜索栏*/ -#searchBar {width:958px; - background-color:#888a85;/*#e9b96e;*/ +#searchBar { + width: 958px; + background-color: #888a85; /*#e9b96e;*/ border: 1px solid #aaaaaa; - padding:4px 0 0 0;} /* #B02B2C */ -#searchBar .content { } -#searchBar .searchInput {font-size:13px; height:18px; width:400px;} -#searchBar .searchBtn {font-size:14px; height:26px; width:80px;} -#searchBar .options {padding:3px 0 3px 0;font-size:100%;color:#EEE; - /*letter-spacing:1px;*/ - } -#searchBar .options INPUT {margin:0 3px 0 15px;} -#searchBar .options INPUT:hover {cursor:pointer} + padding: 4px 0 0 0; +} + +/* #B02B2C */ +#searchBar .content { +} + +#searchBar .searchInput { + font-size: 13px; + height: 18px; + width: 400px; +} + +#searchBar .searchBtn { + font-size: 14px; + height: 26px; + width: 80px; +} + +#searchBar .options { + padding: 3px 0 3px 0; + font-size: 100%; + color: #EEE; /*letter-spacing:1px;*/ +} + +#searchBar .options INPUT { + margin: 0 3px 0 15px; +} + +#searchBar .options INPUT:hover { + cursor: pointer +} /*问题列表*/ -#listA {float:left; background-color:#FFF;padding:0 0px 0 0px; width:100%;} +#listA { + float: left; + background-color: #FFF; + padding: 0 0px 0 0px; + width: 100%; +} + #listA .qstA { - position:relative; - padding:3px 5px 5px 10px; - border-top:1px dashed #ccccce; + position: relative; + padding: 3px 5px 5px 10px; + border-top: 1px dashed #ccccce; /*border-left:1px solid #ebebbe; border-right:1px solid #b4b48e; border-bottom:1px solid #b4b48e;*/ - background: white;/* #f9f7ed;*/ - /*margin:10px 0 10px 0;*/ - /*background:url(../images/quest-bg.gif) repeat-x top;*/ + background: white; /* #f9f7ed;*/ +/*margin:10px 0 10px 0;*/ +/*background:url(../images/quest-bg.gif) repeat-x top;*/ +} + +#listA .qstA thumb { + float: left; +} + +#listA .qstA H2 { + font-size: 14px; + font-weight: 800; + margin: 8px auto; + padding: 0px; +} + +#listA .qstA H2 a { + color: 333333 /*#2e3436*/; + font-size: 15px; } -#listA .qstA thumb {float:left; } -#listA .qstA H2 {font-size:14px; font-weight:800; margin:8px auto;padding:0px;} -#listA .qstA H2 a {color:333333/*#2e3436*/;font-size:15px;} + #listA .qstA .stat { - position:absolute; - right:0px; - bottom:5px; - font-size:12px; - /*letter-spacing:1px;*/ - float:right; -} -#listA .qstA .stat span {margin-right:5px;} -#listA .qstA .stat td {min-width:40px;text-align:center;} + position: absolute; + right: 0px; + bottom: 5px; + font-size: 12px; /*letter-spacing:1px;*/ + float: right; +} + +#listA .qstA .stat span { + margin-right: 5px; +} + +#listA .qstA .stat td { + min-width: 40px; + text-align: center; +} + #listA .qstA .stat .num { - font-family:sans-serif; - color:#a40000; + font-family: sans-serif; + color: #a40000; /*background:#eeeeec; - border: 1px solid #babdb6;*/ - margin:0px; - font-size:17px; - font-weight:800; -} -#listA .qstA table {border-spacing:0px;} -#listA .qstA table td {padding:0px;width:60px;text-align:center;} -#listA .qstA .stat .unit {color:#777777;margin:0px} -#listA .qstA .from {margin-top:5px; font-size:13px;color:#777777;} -#listA .qstA .from .score {font-family:sans-serif;color:#555555;} -#listA .qstA .date {margin-left:10px; color:#777777;} -#listA .qstA .wiki {color:#763333;font-size:12px;} -#listA .qstA .from a {} -#listA .qstA .from IMG {vertical-align:middle;} -#listA .qstA .author {font-weight:400; } -#listA .qstA .author a{color:#444444; } -#listA .qstA .summary{margin-right:5px;} + border: 1px solid #babdb6;*/ + margin: 0px; + font-size: 17px; + font-weight: 800; +} + +#listA .qstA table { + border-spacing: 0px; +} + +#listA .qstA table td { + padding: 0px; + width: 60px; + text-align: center; +} + +#listA .qstA .stat .unit { + color: #777777; + margin: 0px +} + +#listA .qstA .from { + margin-top: 5px; + font-size: 13px; + color: #777777; +} + +#listA .qstA .from .score { + font-family: sans-serif; + color: #555555; +} + +#listA .qstA .date { + margin-left: 10px; + color: #777777; +} + +#listA .qstA .wiki { + color: #763333; + font-size: 12px; +} + +#listA .qstA .from a { +} + +#listA .qstA .from IMG { + vertical-align: middle; +} + +#listA .qstA .author { + font-weight: 400; +} + +#listA .qstA .author a { + color: #444444; +} + +#listA .qstA .summary { + margin-right: 5px; +} + +.short-summary { + position: relative; + padding: 3px 5px 5px 10px; + border-top: 1px dotted #ccccce; + overflow: hidden; + width: 700px; + float: left; +} + +.short-summary h2 { + font-size: 16px; + font-family: "Trebuchet MS", "segoe ui", arial, sans-serif; +} + +.short-summary .userinfo { + float: right; + margin-top: 8px; +} + +.short-summary .counts { + float: right; + margin-top: 4px; +} + +.short-summary .counts .item-count { + font-size: 17px; + font-weight: 800; +} + +.short-summary .votes, +.short-summary .status, +.short-summary .views { + font-size: 12px; + text-align: center; + margin: 0 0 0 7px; + padding: 4px 2px 0px 2px; + width: 46px; + height: 48px; + float: left; + -moz-border-radius: 5px; + -khtml-border-radius: 5px; + -webkit-border-radius: 5px; +} + #question-table { - margin-bottom:10px; - /*border-bottom:1px solid #888a85;*/ + margin-bottom: 10px; /*border-bottom:1px solid #888a85;*/ } -.evenMore {font-size:14px; font-weight:800;} -.questions-count{ - font-size:32px; - font-family:sans-serif; - font-weight:600; - padding:0 0 5px 0px; - color:#a40000; - margin-top:3px; + +.evenMore { + font-size: 14px; + font-weight: 800; +} + +.questions-count { + font-size: 32px; + font-family: sans-serif; + font-weight: 600; + padding: 0 0 5px 0px; + color: #a40000; + margin-top: 3px; } /*内容块*/ -.boxA {background:#888a85; padding:6px; margin-bottom:8px;border 1px solid #babdb6;} -.boxA H3 {font-size:13px; font-weight:800; color:#FFF; margin:0; padding:0; margin-bottom:4px;} -.boxA .body {border:1px solid #999; padding:8px; background:#FFF; font-size:13px;} -.boxA .more {padding:2px; text-align:right; font-weight:800;} -.boxB {background:#F9F7ED; padding:6px; margin-bottom:8px;border:solid 1px #aaaaaa;} -.boxB H3 {font-size:13px; font-weight:800; color:#000; margin:0; padding:0 0 0 15px; margin-bottom:4px; background:url(../images/dot-g.gif) no-repeat left center;} -.boxB .body {border:1px solid #aaaaaa; padding:8px; background:#FFF; font-size:13px; line-height:160%;} -.boxB .more {padding:1px; text-align:right; font-weight:800;} +.boxA { + background: #888a85; + padding: 6px; + margin-bottom: 8px; + border 1px solid #babdb6; +} + +.boxA H3 { + font-size: 13px; + font-weight: 800; + color: #FFF; + margin: 0; + padding: 0; + margin-bottom: 4px; +} + +.boxA .body { + border: 1px solid #999; + padding: 8px; + background: #FFF; + font-size: 13px; +} + +.boxA .more { + padding: 2px; + text-align: right; + font-weight: 800; +} + +.boxB { + background: #F9F7ED; + padding: 6px; + margin-bottom: 8px; + border: solid 1px #aaaaaa; +} + +.boxB H3 { + font-size: 13px; + font-weight: 800; + color: #000; + margin: 0; + padding: 0 0 0 15px; + margin-bottom: 4px; + background: url(../images/dot-g.gif) no-repeat left center; +} + +.boxB .body { + border: 1px solid #aaaaaa; + padding: 8px; + background: #FFF; + font-size: 13px; + line-height: 160%; +} + +.boxB .more { + padding: 1px; + text-align: right; + font-weight: 800; +} + .boxC { - background: #cacdc6;/*f9f7ed;*/ - padding:10px; - margin-bottom:8px; - border-top:1px solid #eeeeec; - border-left:1px solid #eeeeec; - border-right:1px solid #a9aca5; - border-bottom:1px solid #babdb6; + background: #cacdc6; /*f9f7ed;*/ + padding: 10px; + margin-bottom: 8px; + border-top: 1px solid #eeeeec; + border-left: 1px solid #eeeeec; + border-right: 1px solid #a9aca5; + border-bottom: 1px solid #babdb6; } + .boxC p { - margin-bottom:8px; + margin-bottom: 8px; } + .boxC p.nomargin { - margin:0px; + margin: 0px; } + .boxC p.info-box-follow-up-links { - text-align:right; - margin:0; + text-align: right; + margin: 0; } + /*分页*/ -.pager {margin-top:10px; margin-bottom:16px; float:left;} -.pagesize {margin-top:10px; margin-bottom:16px; float:right;} +.pager { + margin-top: 10px; + margin-bottom: 16px; + float: left; +} + +.pagesize { + margin-top: 10px; + margin-bottom: 16px; + float: right; +} /** PAGINATOR **/ .paginator { - padding:5px 0 10px 0; - font:normal 12px sans-serif; + padding: 5px 0 10px 0; + font: normal 12px sans-serif; } .paginator .prev-na, .paginator .next-na { - padding:.3em; - font:bold .875em sans-serif; + padding: .3em; + font: bold .875em sans-serif; } .paginator .prev-na, .paginator .next-na { - border:1px solid #ccc; - background-color:#f9f9f9; - color:#aaa; - font-weight:normal; + border: 1px solid #ccc; + background-color: #f9f9f9; + color: #aaa; + font-weight: normal; } .paginator .prev a, .paginator .prev a:visited, .paginator .next a, .paginator .next a:visited { - border:1px solid #fff; - background-color:#fff; - color:#777; - padding:2px 4px 3px 4px; - font:bold 100% sans-serif; + border: 1px solid #fff; + background-color: #fff; + color: #777; + padding: 2px 4px 3px 4px; + font: bold 100% sans-serif; } -.paginator .prev, .paginator .prev-na { margin-right:.5em; } -.paginator .next, .paginator .next-na { margin-left:.5em; } +.paginator .prev, .paginator .prev-na { + margin-right: .5em; +} + +.paginator .next, .paginator .next-na { + margin-left: .5em; +} .paginator .page a, .paginator .page a:visited, .paginator .curr { - padding:.25em; - font:normal .875em verdana; - border:1px solid #ccc; - background-color:#fff; - margin:0em .25em; - color:#777; + padding: .25em; + font: normal .875em verdana; + border: 1px solid #ccc; + background-color: #fff; + margin: 0em .25em; + color: #777; } .paginator .curr { - background-color:#777; - color:#fff; - border:1px solid #777; - font-weight:bold; + background-color: #777; + color: #fff; + border: 1px solid #777; + font-weight: bold; } .paginator .page a:hover, .paginator .curr a:hover, .paginator .prev a:hover, .paginator .next a:hover { - color:#fff; - background-color:#777; - border:1px solid #777; - text-decoration:none; + color: #fff; + background-color: #777; + border: 1px solid #777; + text-decoration: none; } -.paginator .text{ - color:#777; - padding:.3em; - font:bold 100% sans-serif; +.paginator .text { + color: #777; + padding: .3em; + font: bold 100% sans-serif; } -.paginator-container{ - float:right; - padding:10px 0 10px 0; +.paginator-container { + float: right; + padding: 10px 0 10px 0; } -.paginator-container-left{ - padding:5px 0 10px 0; +.paginator-container-left { + padding: 5px 0 10px 0; } /*标签*/ -.tag {font-size:13px; font-weight:normal; color:#333; text-decoration:none;background-color:#EEE; border-left:3px solid #777; border-top:1px solid #EEE; border-bottom:1px solid #CCC; border-right:1px solid #CCC; padding:1px 8px 1px 8px;} -.tags {font-family:sans-serif; line-height:200%; display:block; margin-top:5px;} -.tags a {white-space: nowrap; font-size:13px; font-weight:normal; color:#333; text-decoration:none;background-color:#EEE; border-left:3px solid #777; border-top:1px solid #EEE; border-bottom:1px solid #CCC; border-right:1px solid #CCC; padding:1px 8px 1px 8px;} -.tags a:hover {background-color:#fFF;color:#333;} -.tagsbox {line-height:200%;} -.tagsbox a {font-size:13px; font-weight:normal; color:#333; text-decoration:none;background-color:#EEE; border-left:3px solid #777; border-top:1px solid #EEE; border-bottom:1px solid #CCC; border-right:1px solid #CCC; padding:1px 8px 1px 8px;} -.tagsbox a:hover {background-color:#fFF;color:#333;} -.tag-number {font-weight:700;font-family:sans-serif;} -.marked-tags { margin-top: 0px;margin-bottom: 5px; } -.deletable-tag { margin-right: 3px; white-space:nowrap; } +.tag { + font-size: 13px; + font-weight: normal; + color: #333; + text-decoration: none; + background-color: #EEE; + border-left: 3px solid #777; + border-top: 1px solid #EEE; + border-bottom: 1px solid #CCC; + border-right: 1px solid #CCC; + padding: 1px 8px 1px 8px; +} + +.tags { + font-family: sans-serif; + line-height: 200%; + display: block; + margin-top: 5px; +} + +.tags a { + white-space: nowrap; + font-size: 13px; + font-weight: normal; + color: #333; + text-decoration: none; + background-color: #EEE; + border-left: 3px solid #777; + border-top: 1px solid #EEE; + border-bottom: 1px solid #CCC; + border-right: 1px solid #CCC; + padding: 1px 8px 1px 8px; +} + +.tags a:hover { + background-color: #fFF; + color: #333; +} + +.tagsbox { + line-height: 200%; +} + +.tagsbox a { + font-size: 13px; + font-weight: normal; + color: #333; + text-decoration: none; + background-color: #EEE; + border-left: 3px solid #777; + border-top: 1px solid #EEE; + border-bottom: 1px solid #CCC; + border-right: 1px solid #CCC; + padding: 1px 8px 1px 8px; +} + +.tagsbox a:hover { + background-color: #fFF; + color: #333; +} + +.tag-number { + font-weight: 700; + font-family: sans-serif; +} + +.marked-tags { + margin-top: 0px; + margin-bottom: 5px; +} + +.deletable-tag { + margin-right: 3px; + white-space: nowrap; +} /*奖牌*/ -a.medal { font-size:14px; line-height:250%; font-weight:800; color:#333; text-decoration:none; background:url(../images/medala.gif) no-repeat; border-left:1px solid #EEE; border-top:1px solid #EEE; border-bottom:1px solid #CCC; border-right:1px solid #CCC; padding:4px 12px 4px 6px;} -a:hover.medal {color:#333; text-decoration:none; background:url(../images/medala_on.gif) no-repeat; border-left:1px solid #E7E296; border-top:1px solid #E7E296; border-bottom:1px solid #D1CA3D; border-right:1px solid #D1CA3D;} +a.medal { + font-size: 14px; + line-height: 250%; + font-weight: 800; + color: #333; + text-decoration: none; + background: url(../images/medala.gif) no-repeat; + border-left: 1px solid #EEE; + border-top: 1px solid #EEE; + border-bottom: 1px solid #CCC; + border-right: 1px solid #CCC; + padding: 4px 12px 4px 6px; +} + +a:hover.medal { + color: #333; + text-decoration: none; + background: url(../images/medala_on.gif) no-repeat; + border-left: 1px solid #E7E296; + border-top: 1px solid #E7E296; + border-bottom: 1px solid #D1CA3D; + border-right: 1px solid #D1CA3D; +} /*Tab栏*/ -.tabBar{background-color:#FFF;border-bottom: 1px solid white;height: 30px; width: 100%;clear:both; margin-bottom:3px;} -.tabsA {background-color:#FFF;float:right;position:relative;display:block;font-weight:bold;height:20px;} -.tabsB {background-color:#FFF;float:left;position:relative;display:block;font-weight:bold;height:20px;} -.tabsA a.on, .tabsA a:hover,.tabsB a.on, .tabsB a:hover { +.tabBar { + background-color: #FFF; + border-bottom: 1px solid white; + height: 30px; + width: 100%; + clear: both; + margin-bottom: 3px; +} + +.tabsA { + background-color: #FFF; + float: right; + position: relative; + display: block; + font-weight: bold; + height: 20px; +} + +.tabsB { + background-color: #FFF; + float: left; + position: relative; + display: block; + font-weight: bold; + height: 20px; +} + +.tabsA a.on, .tabsA a:hover, .tabsB a.on, .tabsB a:hover { background: #fff; - color:#a40000; - border-top:1px solid #babdb6; - border-left:1px solid #babdb6; - border-right:1px solid #888a85; - border-bottom:1px solid #888a85; - height: 24px; - line-height: 26px; - margin-top: 3px; - padding: 0px 11px 0px 11px;} + color: #a40000; + border-top: 1px solid #babdb6; + border-left: 1px solid #babdb6; + border-right: 1px solid #888a85; + border-bottom: 1px solid #888a85; + height: 24px; + line-height: 26px; + margin-top: 3px; + padding: 0px 11px 0px 11px; +} .tabsA a { background: #f9f7eb; - border-top:1px solid #eeeeec; - border-left:1px solid #eeeeec; - border-right:1px solid #a9aca5; - border-bottom:1px solid #888a85; - color: #888a85; - display: block; - float: left; - height: 20px; - line-height: 22px; - margin: 5px 4px 0 0; - padding: 0 11px 0 11px; - text-decoration: none; -} -.tabsB a {background: #eee; - border: 1px solid #eee; - color: #777; - display: block; - float: left; - height: 22px; - line-height: 28px; - margin: 5px 0px 0 4px; - padding: 0 11px 0 11px; - text-decoration: none; + border-top: 1px solid #eeeeec; + border-left: 1px solid #eeeeec; + border-right: 1px solid #a9aca5; + border-bottom: 1px solid #888a85; + color: #888a85; + display: block; + float: left; + height: 20px; + line-height: 22px; + margin: 5px 4px 0 0; + padding: 0 11px 0 11px; + text-decoration: none; +} + +.tabsB a { + background: #eee; + border: 1px solid #eee; + color: #777; + display: block; + float: left; + height: 22px; + line-height: 28px; + margin: 5px 0px 0 4px; + padding: 0 11px 0 11px; + text-decoration: none; } + /*.tabsA a:hover, .tabsB a:hover {background: #fff;border: 1px solid #777;border-bottom:3px solid #FFF;}*/ -.headlineA {font-size:13px; border-bottom:1px solid #777; padding-bottom:2px; font-weight:800; margin-bottom:12px; text-align:right; height:30px;} -.headQuestions {float:left; height:23px; line-height:23px; margin:5px 0 0 5px;padding:0px 6px 0px 15px; font-size:15px; font-weight:700; border-bottom:0px solid #777; border-left:0px solid #darkred; background-color:#FFF;background:url(../images/dot-list.gif) no-repeat left center;} -.headAnswers {float:left; padding:3px; font-size:18px; font-weight:800; background:url(../images/ico_answers.gif) left 2px no-repeat; padding-left:24px;} -.headTags {float:left; padding:3px; font-size:18px; font-weight:800; background:url(../images/ico_tags.gif) no-repeat; padding-left:24px;} -.headUsers {float:left; height:23px; line-height:23px; margin:5px 0 0 5px;padding:0px 6px 0px 15px; font-size:15px; font-weight:700; border-bottom:0px solid #777; border-left:0px solid #darkred; background-color:#FFF;background:url(../images/dot-list.gif) no-repeat left center;} -.headMedals {float:left; height:23px; line-height:23px; margin:5px 0 0 5px;padding:0px 6px 0px 15px; font-size:15px; font-weight:700; border-bottom:0px solid #777; border-left:0px solid #darkred; background-color:#FFF;background:url(../images/dot-list.gif) no-repeat left center;} -.headLogin {float:left; padding:3px; font-size:15px; font-weight:800; background:url(../images/ico_login.gif) no-repeat; padding-left:24px;} +.headlineA { + font-size: 13px; + border-bottom: 1px solid #777; + padding-bottom: 2px; + font-weight: 800; + margin-bottom: 12px; + text-align: right; + height: 30px; +} + +.headQuestions { + float: left; + height: 23px; + line-height: 23px; + margin: 5px 0 0 5px; + padding: 0px 6px 0px 15px; + font-size: 15px; + font-weight: 700; + border-bottom: 0px solid #777; + border-left: 0px solid #darkred; + background-color: #FFF; + background: url(../images/dot-list.gif) no-repeat left center; +} + +.headAnswers { + float: left; + padding: 3px; + font-size: 18px; + font-weight: 800; + background: url(../images/ico_answers.gif) left 2px no-repeat; + padding-left: 24px; +} + +.headTags { + float: left; + padding: 3px; + font-size: 18px; + font-weight: 800; + background: url(../images/ico_tags.gif) no-repeat; + padding-left: 24px; +} + +.headUsers { + float: left; + height: 23px; + line-height: 23px; + margin: 5px 0 0 5px; + padding: 0px 6px 0px 15px; + font-size: 15px; + font-weight: 700; + border-bottom: 0px solid #777; + border-left: 0px solid #darkred; + background-color: #FFF; + background: url(../images/dot-list.gif) no-repeat left center; +} + +.headMedals { + float: left; + height: 23px; + line-height: 23px; + margin: 5px 0 0 5px; + padding: 0px 6px 0px 15px; + font-size: 15px; + font-weight: 700; + border-bottom: 0px solid #777; + border-left: 0px solid #darkred; + background-color: #FFF; + background: url(../images/dot-list.gif) no-repeat left center; +} + +.headLogin { + float: left; + padding: 3px; + font-size: 15px; + font-weight: 800; + background: url(../images/ico_login.gif) no-repeat; + padding-left: 24px; +} + .headNormal { - text-align:left; - padding:3px; - font-size:15px; - margin-bottom:12px; - font-weight:bold; - border-bottom: 1px solid #777; -} -.headUser {text-align:left;padding:5px; font-size:20px; - /*letter-spacing:1px;*/ - margin-bottom:12px; font-weight:800;border-bottom:1px solid #777;} + text-align: left; + padding: 3px; + font-size: 15px; + margin-bottom: 12px; + font-weight: bold; + border-bottom: 1px solid #777; +} + +.headUser { + text-align: left; + padding: 5px; + font-size: 20px; /*letter-spacing:1px;*/ + margin-bottom: 12px; + font-weight: 800; + border-bottom: 1px solid #777; +} + /*RSS订阅*/ -#feeds {margin:10px 0; } -#feeds a {background:url(../images/feed-icon-small.png) no-repeat 0; padding-left:18px; font-weight:700; font-size:13px; } +#feeds { + margin: 10px 0; +} + +#feeds a { + background: url(../images/feed-icon-small.png) no-repeat 0; + padding-left: 18px; + font-weight: 700; + font-size: 13px; +} /*问题*/ -#question {margin-bottom:30px;} -#question h1{font-size:15px;background:#CCC; padding:6px 8px;;} -#question .body{background:#F7F7F7; padding:20px 10px;} -.starter {padding:10px; background:#E0EAF1;} -.vote {font-size:20px; color:#666; font-weight:800;} -.questions-related{font-weight:700;word-wrap:break-word;} -.questions-related p{line-height:20px; margin-bottom:10px;font-size:100%;} -.question-status{ - margin-top:10px; +#question { + margin-bottom: 30px; +} + +#question h1 { + font-size: 15px; + background: #CCC; + padding: 6px 8px;; +} + +#question .body { + background: #F7F7F7; + padding: 20px 10px; +} + +.starter { + padding: 10px; + background: #E0EAF1; +} + +.vote { + font-size: 20px; + color: #666; + font-weight: 800; +} + +.questions-related { + font-weight: 700; + word-wrap: break-word; +} + +.questions-related p { + line-height: 20px; + margin-bottom: 10px; + font-size: 100%; +} + +.question-status { + margin-top: 10px; padding: 20px; - background-color:#F5F5F5; - text-align:center; + background-color: #F5F5F5; + text-align: center; +} + +.question-status h3 { + font-size: 125%; } -.question-status h3{font-size:125%;} -.question-body{ - min-height:100px; - font-size:13px; - line-height:20px; + +.question-body { + min-height: 100px; + font-size: 13px; + line-height: 20px; } -.question-body IMG{ - max-width:600px; + +.question-body IMG { + max-width: 600px; } -.question-mark{ + +.question-mark { /*background-color:#fff5e0; border-top: 1px solid #eeeeec; border-right: 1px solid #babdb6; border-bottom: 1px solid #babdb6; border-left: 1px solid #eeeeec;*/ - text-align:left; - padding:5px; - overflow:hidden; -} -.question-edit{ - text-align:left; - overflow:hidden; -} -.vote-buttons {float:left;text-align:center;} -.vote-buttons IMG{cursor:pointer;} -.vote-number{ - font-family:Arial; - padding:0px 0 3px 0; - font-size:140%; - font-weight:bold; - color:#777; -} -.question-img-upvote:hover{background:url(../images/vote-arrow-up-on.png)} -.question-img-downvote:hover{background:url(../images/vote-arrow-down-on.png)} -.question-img-favorite:hover{background:url(../images/vote-favorite-on.png)} -.favorite-number{padding:0px;font-size:100%; font-family:Arial;font-weight:bold;color:#777;} -.vote-notification -{ - z-index: 1; - cursor: pointer; - display: none; - position: absolute; - padding: 15px; + text-align: left; + padding: 5px; + overflow: hidden; +} + +.question-edit { + text-align: left; + overflow: hidden; +} + +.vote-buttons { + float: left; + text-align: center; +} + +.vote-buttons IMG { + cursor: pointer; +} + +.vote-number { + font-family: Arial; + padding: 0px 0 3px 0; + font-size: 140%; + font-weight: bold; + color: #777; +} + +.question-img-upvote:hover { + background: url(../images/vote-arrow-up-on.png) +} + +.question-img-downvote:hover { + background: url(../images/vote-arrow-down-on.png) +} + +.question-img-favorite:hover { + background: url(../images/vote-favorite-on.png) +} + +.favorite-number { + padding: 0px; + font-size: 100%; + font-family: Arial; + font-weight: bold; + color: #777; +} + +.vote-notification { + z-index: 1; + cursor: pointer; + display: none; + position: absolute; + padding: 15px; color: White; - background-color: darkred; - text-align: center; + background-color: darkred; + text-align: center; } -.vote-notification a -{ + +.vote-notification a { color: White; - text-decoration:underline; + text-decoration: underline; } -.offensive-flag a{ - color:#777; - padding:3px; - cursor:pointer; + +.offensive-flag a { + color: #777; + padding: 3px; + cursor: pointer; } -.offensive-flag a:hover{ - background-color:#777; - text-decoration:none; - color:#fff; +.offensive-flag a:hover { + background-color: #777; + text-decoration: none; + color: #fff; } -.linksopt a{ - color:#777; - padding:3px; - cursor:pointer; +.linksopt a { + color: #777; + padding: 3px; + cursor: pointer; } -.linksopt a:hover{ - background-color:#777; - text-decoration:none; - color:#fff; +.linksopt a:hover { + background-color: #777; + text-decoration: none; + color: #fff; } -.action-link a{ - color:#777; - padding:3px; - cursor:pointer; +.action-link a { + color: #777; + padding: 3px; + cursor: pointer; } -.action-link: a hover{ - background-color:#777; - text-decoration:none; - color:#fff; +.action-link: a hover { + background-color: #777; + text-decoration: none; + color: #fff; } -.action-link-separator{ - color:#ccc; + +.action-link-separator { + color: #ccc; } -.wiki-category{ - margin-left:5px; - color:#999; - font-size:90%; + +.wiki-category { + margin-left: 5px; + color: #999; + font-size: 90%; } div.comments { - line-height:150%; - padding:10px 0; + line-height: 150%; + padding: 10px 0; } -div.post-comments{ - clear:both; +div.post-comments { + clear: both; background: url(../images/gray-up-arrow-h18px.png) no-repeat; - width:100%; + width: 100%; padding-left: 12px; - margin:3px 0 10px 0; + margin: 3px 0 10px 0; } form.post-comments textarea { - height:6em; - margin-bottom:4px; + height: 6em; + margin-bottom: 4px; } form.post-comments input { - margin-left:10px; - margin-top:1px; - vertical-align:top; - width:100px; + margin-left: 10px; + margin-top: 1px; + vertical-align: top; + width: 100px; } + span.text-counter { - margin-right:20px; - font-size:11px; + margin-right: 20px; + font-size: 11px; } span.form-error { - color:#990000; - font-weight:normal; - margin-left:5px; + color: #990000; + font-weight: normal; + margin-left: 5px; } + p.form-item { - margin:0px; + margin: 0px; } div.comments-container, div.comments-container-accepted, div.comments-container-owner, div.comments-container-deleted { - padding:0; + padding: 0; } .post-comments a { - color:#888888; - padding:0 3px 2px; + color: #888888; + padding: 0 3px 2px; } a.comments-link, a.comments-link-accepted, a.comments-link-owner, a.comments-link-deleted { - color:black; - font-size:11px; + color: black; + font-size: 11px; background: #eeeeee; - padding:3px; - cursor:pointer; + padding: 3px; + cursor: pointer; } .post-comments a:hover { - background-color:#777777; - color:white; - text-decoration:none; + background-color: #777777; + color: white; + text-decoration: none; } a.comment-user, a.comment-user:hover { - background-color:inherit; - color:blue; - padding:0; + background-color: inherit; + color: blue; + padding: 0; } a.comment-user:hover { - text-decoration:underline; + text-decoration: underline; } + /*回答*/ -#answers {} -.answer{ - padding-top:10px; +#answers { +} + +.answer { + padding-top: 10px; width: 100%; - border-bottom:1px solid #ccccce; + border-bottom: 1px solid #ccccce; } -.answer-body{ - min-height:80px; - font-size:13px; - line-height:20px; + +.answer-body { + min-height: 80px; + font-size: 13px; + line-height: 20px; } -.answer-body IMG{ - max-width:600px; +.answer-body IMG { + max-width: 600px; } -.accepted-answer{ - background-color:#EBFFE6; - border-bottom-color:#9BD59B; +.accepted-answer { + background-color: #EBFFE6; + border-bottom-color: #9BD59B; } -.accepted-answer .comments-link{ - background-color:#CCFFBF; +.accepted-answer .comments-link { + background-color: #CCFFBF; } -.accepted-answer .comments-container{ - background-color:#CCFFBF; +.accepted-answer .comments-container { + background-color: #CCFFBF; } -.answered -{ - background: #CCC; - color: #999; +.answered { + background: #CCC; + color: #999; } -.answered-accepted -{ - background: #CCC; - color: #763333; +.answered-accepted { + background: #CCC; + color: #763333; } -.unanswered -{ - background: #777; - color: white; +.unanswered { + background: #777; + color: white; } -.answered-by-owner -{ - background: #E9E9FF; +.answered-by-owner { + background: #E9E9FF; } -.answered-by-owner .comments-link -{ - background-color:#E6ECFF; +.answered-by-owner .comments-link { + background-color: #E6ECFF; } -.answered-by-owner .comments-container -{ - background-color:#E6ECFF; +.answered-by-owner .comments-container { + background-color: #E6ECFF; } -.answered-accepted strong -{ - color: #E1E818; +.answered-accepted strong { + color: #E1E818; } -.answer-img-accept:hover{background:url(../images/vote-accepted-on.png)} +.answer-img-accept:hover { + background: url(../images/vote-accepted-on.png) +} -.deleted{ - background:#F4E7E7 none repeat scroll 0 0; +.deleted { + background: #F4E7E7 none repeat scroll 0 0; } /*标签列表*/ @@ -658,812 +1342,1118 @@ a.comment-user:hover { .tagsbox {} .tagsbox a {color:#000;line-height:30px;margin-right:10px;font-size:100%;background-color:#F9F7ED;padding:3px;border:1px solid #aaaaaa;} .tagsbox a:hover {text-decoration:none;background-color:#F9F7ED;color:#B02B2C;} */ -.tagsList {margin:0; list-style-type:none;padding:0px;min-height:360px;} -.tagsList li {width:235px; float:left;} -.badge-list{margin:0; list-style-type:none;} +.tagsList { + margin: 0; + list-style-type: none; + padding: 0px; + min-height: 360px; +} + +.tagsList li { + width: 235px; + float: left; +} + +.badge-list { + margin: 0; + list-style-type: none; +} + /*登录*/ -.list-item{margin-left:15px;} -.list-item LI{list-style-type:disc; font-size:13px; line-height:20px; margin-bottom:10px;} +.list-item { + margin-left: 15px; +} + +.list-item LI { + list-style-type: disc; + font-size: 13px; + line-height: 20px; + margin-bottom: 10px; +} + /* openid styles */ -.form-row{line-height:25px;} +.form-row { + line-height: 25px; +} + table.form-as-table { - margin-top:5px; + margin-top: 5px; } + table.form-as-table ul { - list-style-type:none; + list-style-type: none; display: inline; } + table.form-as-table li { display: inline; } + table.form-as-table td { - text-align:right; + text-align: right; } + table.form-as-table th { - text-align:left; - font-weight:normal; + text-align: left; + font-weight: normal; } + /*.form-row li label { display: inline }*/ -.submit-row{ - line-height:30px; - padding-top:10px; +.submit-row { + line-height: 30px; + padding-top: 10px; display: block; clear: both; } -.errors{line-height:20px;color:red;} -.error{ - color:darkred; - margin:0; + +.errors { + line-height: 20px; + color: red; +} + +.error { + color: darkred; + margin: 0; font-size: 10px; } -.error-list li{padding:5px;} -.fieldset{ + +.error-list li { + padding: 5px; +} + +.fieldset { /* border:solid 1px #777;*/ - border: none; - margin-top:10px; - padding:10px; + border: none; + margin-top: 10px; + padding: 10px; } -.openid-input{background:url(../images/openid.gif) no-repeat;padding-left:15px;cursor:pointer;} -.openid-login-input{ - background-position:center left; - background:url(../images/openid.gif) no-repeat 0% 50%; - padding:5px 5px 5px 15px; - cursor:pointer; - font-family:Trebuchet MS; - font-weight:300; - font-size:150%; - width:500px; + +.openid-input { + background: url(../images/openid.gif) no-repeat; + padding-left: 15px; + cursor: pointer; } -.openid-login-submit{ - height:40px; - width:80px; - line-height:40px; - cursor:pointer; - border:1px solid #777; - font-weight:bold; - font-size:120%; +.openid-login-input { + background-position: center left; + background: url(../images/openid.gif) no-repeat 0% 50%; + padding: 5px 5px 5px 15px; + cursor: pointer; + font-family: Trebuchet MS; + font-weight: 300; + font-size: 150%; + width: 500px; } -.openid-samples{ +.openid-login-submit { + height: 40px; + width: 80px; + line-height: 40px; + cursor: pointer; + border: 1px solid #777; + font-weight: bold; + font-size: 120%; +} + +.openid-samples { } -.openid-samples .list, .list li{ - font-family:Trebuchet MS,"segoe ui",Helvetica,"Microsoft YaHei",宋体,Tahoma,Verdana,MingLiu,PMingLiu,Arial,sans-serif; - list-style:none !important; - margin-left:-30px !important; - line-height:20px !important; +.openid-samples .list, .list li { + font-family: Trebuchet MS, "segoe ui", Helvetica, "Microsoft YaHei", 宋 体, Tahoma, Verdana, MingLiu, PMingLiu, Arial, sans-serif; + list-style: none !important; + margin-left: -30px !important; + line-height: 20px !important; } /*表单相关*/ span.form-error { - color:#990000; - font-size:90%; - font-weight:normal; - margin-left:5px; + color: #990000; + font-size: 90%; + font-weight: normal; + margin-left: 5px; } -.title-desc{ - color:#666666; - font-size:90%; + +.title-desc { + color: #666666; + font-size: 90%; } /*adjustment for editor preview*/ -#editor{ - font-size:100%; - min-height:200px; +#editor { + font-size: 100%; + min-height: 200px; line-height: 18px; - width:100%; + width: 100%; } -.wmd-preview{ - margin-top:10px; - padding:6px; - width:100%; - background-color:#F5F5F5; - min-height:20px; +.wmd-preview { + margin-top: 10px; + padding: 6px; + width: 100%; + background-color: #F5F5F5; + min-height: 20px; } -.wmd-preview pre{ - background-color:#E7F1F8; + +.wmd-preview pre { + background-color: #E7F1F8; } -.wmd-preview blockquote -{ - background-color: #eee; +.wmd-preview blockquote { + background-color: #eee; } -.wmd-preview IMG{ - max-width:600px; +.wmd-preview IMG { + max-width: 600px; } -.preview-toggle{ - font-weight:600; - width:100%; - color:#aaa; - /*letter-spacing:1px;*/ - text-align:left; + +.preview-toggle { + font-weight: 600; + width: 100%; + color: #aaa; /*letter-spacing:1px;*/ + text-align: left; } -.preview-toggle span:hover{ - cursor:pointer; +.preview-toggle span:hover { + cursor: pointer; } -.edit-content-html{ - border-top:1px dotted #D8D2A9; - border-bottom:1px dotted #D8D2A9; - margin:5px 0 5px 0; +.edit-content-html { + border-top: 1px dotted #D8D2A9; + border-bottom: 1px dotted #D8D2A9; + margin: 5px 0 5px 0; } /*修订记录*/ -#revisions{ - width:950px; +#revisions { + width: 950px; } -.revision{ - margin:10px 0 10px 0; - width:100%; - font-size:13px; +.revision { + margin: 10px 0 10px 0; + width: 100%; + font-size: 13px; } -.revision .header{ - background-color:#eee; - padding:5px; - cursor:pointer; +.revision .header { + background-color: #eee; + padding: 5px; + cursor: pointer; } -.revision .author{ - background-color:#E9E9FF; +.revision .author { + background-color: #E9E9FF; } -.revision .summary{ +.revision .summary { padding: 5px 0 10px 0; } -.revision .summary span{ - background-color:yellow; - padding-left:3px; - padding-right:3px; - display:inline; +.revision .summary span { + background-color: yellow; + padding-left: 3px; + padding-right: 3px; + display: inline; } -.revision h1{ - font-size:130%; - font-weight:600; - padding:15px 0 15px 0; + +.revision h1 { + font-size: 130%; + font-weight: 600; + padding: 15px 0 15px 0; } -.revision-mark{ - width:200px; - text-align:left; - display:inline-block; - font-size:90%; - overflow:hidden; +.revision-mark { + width: 200px; + text-align: left; + display: inline-block; + font-size: 90%; + overflow: hidden; } -.revision-number{ - font-size:300%; - font-weight:bold; - font-family:sans-serif; +.revision-number { + font-size: 300%; + font-weight: bold; + font-family: sans-serif; } -.revision .body{ - padding-left:10px; - margin-bottom:50px; +.revision .body { + padding-left: 10px; + margin-bottom: 50px; } -.revision .answerbody{ - padding:10px 0 5px 10px; + +.revision .answerbody { + padding: 10px 0 5px 10px; } /* Revision pages */ -del { color: #FF5F5F; } -del .post-tag{ -color: #FF5F5F; +del { + color: #FF5F5F; +} + +del .post-tag { + color: #FF5F5F; } -ins { background-color: #97ff97;} -ins .post-tag{ -background-color: #97ff97; + +ins { + background-color: #97ff97; +} + +ins .post-tag { + background-color: #97ff97; } /*用户资料页面*/ -.count {font-family:Arial;font-size:200%;font-weight:700;color:#777} -.scoreNumber{font-family:Arial;font-size:35px;font-weight:800;color:#777;line-height:40px; - /*letter-spacing:0px*/ - } -.user-details{font-size:13px;} -.user-about{background-color:#EEEEEE;height:200px;line-height:20px; overflow:auto;padding:10px;width:90%;} -.user-edit-link {background:url(../images/edit.png) no-repeat; padding-left:20px;} +.count { + font-family: Arial; + font-size: 200%; + font-weight: 700; + color: #777 +} + +.scoreNumber { + font-family: Arial; + font-size: 35px; + font-weight: 800; + color: #777; + line-height: 40px; /*letter-spacing:0px*/ +} + +.user-details { + font-size: 13px; +} + +.user-about { + background-color: #EEEEEE; + height: 200px; + line-height: 20px; + overflow: auto; + padding: 10px; + width: 90%; +} + +.user-edit-link { + background: url(../images/edit.png) no-repeat; + padding-left: 20px; +} + .favorites-count-off { - color:#919191; - float:left; - padding:3px; - margin:10px 0 0 0 ; - text-align:center; + color: #919191; + float: left; + padding: 3px; + margin: 10px 0 0 0; + text-align: center; } .favorites-count { - color:#D4A849; - float:left; - padding:3px; - margin:10px 0 0 0 ; - text-align:center; + color: #D4A849; + float: left; + padding: 3px; + margin: 10px 0 0 0; + text-align: center; } -.favorites-empty{ - width: 32px; height: 45px; float: left; + +.favorites-empty { + width: 32px; + height: 45px; + float: left; } + .question-summary { - border-bottom:1px dotted #999999; - float:left; - overflow:hidden; - padding:11px 0; - width:670px; + border-bottom: 1px dotted #999999; + float: left; + overflow: hidden; + padding: 11px 0; + width: 670px; } -.user-info-table{ -width:950;margin-bottom:10px; +.user-info-table { + width: 950; + margin-bottom: 10px; } .user-stats-table .question-summary { - width:800px; + width: 800px; } .narrow .stats { - background:transparent none repeat scroll 0 0; - float:left; - height:48px; - margin:0 0 0 7px; - padding:0; - width:auto; - font-family:Arial; + background: transparent none repeat scroll 0 0; + float: left; + height: 48px; + margin: 0 0 0 7px; + padding: 0; + width: auto; + font-family: Arial; } .stats div { - font-size:11px; - text-align:center; + font-size: 11px; + text-align: center; } .narrow .votes { - background:#EEEEEE none repeat scroll 0 0; - float:left; - height:42px; - margin:0 3px 0 0; - padding:5px; - width:46px; - text-align:center; + background: #EEEEEE none repeat scroll 0 0; + float: left; + height: 42px; + margin: 0 3px 0 0; + padding: 5px; + width: 46px; + text-align: center; -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; } .narrow .summary { - width:600px; - display:inline-block; + width: 600px; + display: inline-block; } .narrow .summary h3 { - padding:0px; - margin:0px; + padding: 0px; + margin: 0px; } .narrow .views { - height:42px; - float:left; - margin:0 7px 0 0; - /*padding:5px 0 5px 4px;*/ - padding: 5px; - width:46px; - text-align:center; + height: 42px; + float: left; + margin: 0 7px 0 0; /*padding:5px 0 5px 4px;*/ + padding: 5px; + width: 46px; + text-align: center; -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; - color:#777; + color: #777; } .narrow .status { - float:left; - height:42px; - margin:0 3px 0 0; - padding:5px; - width:46px; - text-align:center; + float: left; + height: 42px; + margin: 0 3px 0 0; + padding: 5px; + width: 46px; + text-align: center; -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; } .narrow .vote-count-post { - font-weight:800; - display:block; - margin:0; - font-size: 190%; color:#555; line-height:20px; -} -.narrow .answer-count-post{ - font-weight:800; - display:block; - margin:0; - font-size: 190%; -} -.narrow .views-count-post{ - font-weight:800; - display:block; - margin:0; + font-weight: 800; + display: block; + margin: 0; + font-size: 190%; + color: #555; + line-height: 20px; +} + +.narrow .answer-count-post { + font-weight: 800; + display: block; + margin: 0; + font-size: 190%; +} + +.narrow .views-count-post { + font-weight: 800; + display: block; + margin: 0; font-size: 190%; } + div.started { - color:#999999; - float:right; - line-height:18px; - + color: #999999; + float: right; + line-height: 18px; + } .narrow div.started { - line-height:inherit; - padding-top:4px; - white-space:nowrap; - width:auto; + line-height: inherit; + padding-top: 4px; + white-space: nowrap; + width: auto; } .relativetime { - font-weight:bold; - text-decoration:none; + font-weight: bold; + text-decoration: none; } div.started a { - font-weight:bold; + font-weight: bold; } div.started .reputation-score { - margin-left:1px; + margin-left: 1px; } -.narrow .tags{float:left;} +.narrow .tags { + float: left; +} .answer-summary { - display:block; - clear:both; - padding:3px; + display: block; + clear: both; + padding: 3px; } .answer-votes { - background-color:#EEEEEE; - color:#555555; - float:left; - font-family:Arial; - font-size:110%; - font-weight:bold; - height:15px; - padding:4px 4px 5px; - text-align:center; - text-decoration:none; - width:20px; - margin-right:10px; + background-color: #EEEEEE; + color: #555555; + float: left; + font-family: Arial; + font-size: 110%; + font-weight: bold; + height: 15px; + padding: 4px 4px 5px; + text-align: center; + text-decoration: none; + width: 20px; + margin-right: 10px; +} + +.vote-count { + font-family: Arial; + font-size: 160%; + font-weight: 700; + color: #777; } -.vote-count{font-family:Arial; font-size:160%; font-weight:700; color:#777;} -.user-action{ + +.user-action { } -.user-action-1{ - font-weight:bold; - color:#333; + +.user-action-1 { + font-weight: bold; + color: #333; } -.user-action-2{ - font-weight:bold; - color:#CCC; + +.user-action-2 { + font-weight: bold; + color: #CCC; } -.user-action-3{ - color:#333; + +.user-action-3 { + color: #333; } -.user-action-4{ - color:#333; + +.user-action-4 { + color: #333; } -.user-action-5{ - color:darkred; + +.user-action-5 { + color: darkred; } -.user-action-6{ - color:darkred; + +.user-action-6 { + color: darkred; } -.user-action-7{ - color:#333; + +.user-action-7 { + color: #333; } -.user-action-8{ - padding:3px; - font-weight:bold; - background-color:#CCC; - color:#763333; + +.user-action-8 { + padding: 3px; + font-weight: bold; + background-color: #CCC; + color: #763333; } -.revision-summary{ - background-color:#FFFE9B; - padding:2px; +.revision-summary { + background-color: #FFFE9B; + padding: 2px; } -.question-title-link a{ - font-weight:bold; - color:#0077CC; + +.question-title-link a { + font-weight: bold; + color: #0077CC; } -.answer-title-link a{ - color:#333; + +.answer-title-link a { + color: #333; } .post-type-1 a { - font-weight:bold; - + font-weight: bold; + } + .post-type-3 a { - font-weight:bold; - + font-weight: bold; + } + .post-type-5 a { - font-weight:bold; - } -.post-type-2 a{ - color:#333; + font-weight: bold; } -.post-type-4 a{ - color:#333; + +.post-type-2 a { + color: #333; } -.post-type-6 a{ - color:#333; + +.post-type-4 a { + color: #333; } -.post-type-8 a{ - color:#333; + +.post-type-6 a { + color: #333; } +.post-type-8 a { + color: #333; +} /*读书频道*/ -.bookInfo {float:left; width:940px;padding:5px;} -.bookCover {float:left; width:200px;} -.bookCover img{border:1px solid #ccc;max-width:200px;} -.bookSummary {float:left; font-size:13px;} -.blogRss {float:right;margin:0 10px 0 0;width:460px;height:240px;background-color:#EEE; padding:5px;} -.bookQuestions {margin-bottom:10px;} -.bookFeed {float:right;} -.bookAsk{ - /*letter-spacing:1px; */ - float:right;margin:-30px 10px 0 0; padding:3px 5px 3px 5px;} -.bookAsk a {font-size:15px; color:#FFF; font-weight:bold; text-decoration:none;background-color:#EC7000;padding:3px 6px 3px 6px; } -.bookAsk a:hover {text-decoration:underline;} +.bookInfo { + float: left; + width: 940px; + padding: 5px; +} + +.bookCover { + float: left; + width: 200px; +} + +.bookCover img { + border: 1px solid #ccc; + max-width: 200px; +} + +.bookSummary { + float: left; + font-size: 13px; +} + +.blogRss { + float: right; + margin: 0 10px 0 0; + width: 460px; + height: 240px; + background-color: #EEE; + padding: 5px; +} + +.bookQuestions { + margin-bottom: 10px; +} + +.bookFeed { + float: right; +} + +.bookAsk { +/*letter-spacing:1px; */ + float: right; + margin: -30px 10px 0 0; + padding: 3px 5px 3px 5px; +} + +.bookAsk a { + font-size: 15px; + color: #FFF; + font-weight: bold; + text-decoration: none; + background-color: #EC7000; + padding: 3px 6px 3px 6px; +} +.bookAsk a:hover { + text-decoration: underline; +} /*其他全局样式*/ -.hilite { background-color: #ff0; } -.hilite1 { background-color: #ff0; } -.hilite2 { background-color: #f0f; } -.hilite3 { background-color: #0ff; } -.userStatus {margin-left:12px; color:#FFF; float:right;} -.userStatus a {color:#FFF;} -.gold, .badge1 {color:#FFCC00;} -.silver, .badge2 {color:#CCCCCC;} -.bronze, .badge3 {color:#CC9933;} -.score {font-weight:800; color:#333;} -.footerLinks {color:#EEE; font-size:13px; - /* letter-spacing:1px;*/ - } -.footerLinks a {color:#FFF; font-size:13px;} -.subSearch {margin-bottom:12px; padding:4px;} -a.comment {background:#EEE; color:#993300; padding:4px;} -a.permLink {padding:2px;} -a.offensive {color:#999;} -ul.bulleta li {background:url(../images/bullet_green.gif) no-repeat 0px 2px; padding-left:16px; margin-bottom:4px;} -.user {padding:5px; line-height:140%; width:170px;} -.user ul {margin:0; list-style-type:none;} -.user .thumb{clear:both;float:left; margin-right:4px; display:inline;} -.yellowbg{background:yellow;} - -.message{ - padding:5px; - margin:10px 0 10px 0; - background-color:#eee; +.hilite { + background-color: #ff0; +} + +.hilite1 { + background-color: #ff0; +} + +.hilite2 { + background-color: #f0f; +} + +.hilite3 { + background-color: #0ff; +} + +.userStatus { + margin-left: 12px; + color: #FFF; + float: right; +} + +.userStatus a { + color: #FFF; +} + +.gold, .badge1 { + color: #FFCC00; +} + +.silver, .badge2 { + color: #CCCCCC; +} + +.bronze, .badge3 { + color: #CC9933; +} + +.score { + font-weight: 800; + color: #333; +} + +.footerLinks { + color: #EEE; + font-size: 13px; /* letter-spacing:1px;*/ +} + +.footerLinks a { + color: #FFF; + font-size: 13px; +} + +.subSearch { + margin-bottom: 12px; + padding: 4px; +} + +a.comment { + background: #EEE; + color: #993300; + padding: 4px; +} + +a.permLink { + padding: 2px; +} + +a.offensive { + color: #999; +} + +ul.bulleta li { + background: url(../images/bullet_green.gif) no-repeat 0px 2px; + padding-left: 16px; + margin-bottom: 4px; +} + +.user { + padding: 5px; + line-height: 140%; + width: 170px; +} + +.user ul { + margin: 0; + list-style-type: none; +} + +.user .thumb { + clear: both; + float: left; + margin-right: 4px; + display: inline; +} + +.yellowbg { + background: yellow; +} + +.message { + padding: 5px; + margin: 10px 0 10px 0; + background-color: #eee; border: 1px solid #aaaaaa; } + .message h1 { - padding-top:0px; - font-size:15px; + padding-top: 0px; + font-size: 15px; } + .message p { - margin-bottom:0px; + margin-bottom: 0px; } + p.space-above { - margin-top:10px; -} - -.warning{color:red;} -.darkred{color:darkred;} -.submit{ - cursor:pointer; - /*letter-spacing:1px;*/ - background-color:#D4D0C8; - height:40px; - border:1px solid #777777; -/* width:100px; */ - font-weight:bold; - padding-bottom:4px; - font-size:120%;} -.submit:hover{text-decoration:underline;} -.ask-body{padding-right:10px;} -.thousand{color:orange;} - -.notify -{ - position: fixed; - top: 0px; - left: 0px; - width: 100%; - z-index: 100; - padding: 0; - text-align: center; - font-weight: Bold; - color: #444; - background-color: #F4A83D; + margin-top: 10px; +} + +.warning { + color: red; +} + +.darkred { + color: darkred; +} + +.submit { + cursor: pointer; /*letter-spacing:1px;*/ + background-color: #D4D0C8; + height: 40px; + border: 1px solid #777777; /* width:100px; */ + font-weight: bold; + padding-bottom: 4px; + font-size: 120%; +} + +.submit:hover { + text-decoration: underline; +} + +.ask-body { + padding-right: 10px; +} + +.thousand { + color: orange; +} + +.notify { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + z-index: 100; + padding: 0; + text-align: center; + font-weight: Bold; + color: #444; + background-color: #F4A83D; } .notify p { - margin-top:5px; - margin-bottom:5px; - font-size:16px; -} - -#close-notify -{ - position:absolute; - right:5px; - top:5px; - padding:0 3px 0 3px; - color: #735005; - text-decoration: none; - font-size:14px; - line-height:18px; - background-color: #FAD163; - border: 2px #735005 solid; - cursor:pointer; + margin-top: 5px; + margin-bottom: 5px; + font-size: 16px; +} + +#close-notify { + position: absolute; + right: 5px; + top: 5px; + padding: 0 3px 0 3px; + color: #735005; + text-decoration: none; + font-size: 14px; + line-height: 18px; + background-color: #FAD163; + border: 2px #735005 solid; + cursor: pointer; } + #close-notify:hover { - text-decoration:none; + text-decoration: none; } .big { - font-size:15px; + font-size: 15px; } + .bigger { - font-size:14px; + font-size: 14px; } + .strong { - font-weight:bold; + font-weight: bold; } -.orange -{ - color:#d64000; - font-weight:bold; + +.orange { + color: #d64000; + font-weight: bold; } + .grey { - color:#808080; + color: #808080; } + .about div { - padding:10px 5px 10px 5px; - border-top:1px dashed #aaaaaa; + padding: 10px 5px 10px 5px; + border-top: 1px dashed #aaaaaa; } + .about div.first { - padding-top:0; - border-top:none; + padding-top: 0; + border-top: none; } + .about p { - margin-bottom:10px; + margin-bottom: 10px; +} + +.about a { + color: #d64000; + text-decoration: underline; } -.about a {color:#d64000;text-decoration:underline;} -.about h3{ - line-height:30px; - font-size:15px; - font-weight:700; + +.about h3 { + line-height: 30px; + font-size: 15px; + font-weight: 700; padding-top: 0px; } + .highlight { - background-color:#FFF8C6; + background-color: #FFF8C6; } + .nomargin { - margin:0; + margin: 0; } + .margin-bottom { margin-bottom: 10px; } + .margin-top { margin-top: 10px; } + .inline-block { - display:inline-block; + display: inline-block; } + .action-status { - margin:0; - border:none; - text-align:center; - line-height:10px; - font-size:12px; - padding:0; + margin: 0; + border: none; + text-align: center; + line-height: 10px; + font-size: 12px; + padding: 0; } + .action-status span { - padding:3px 5px 3px 5px; - background-color:#fff380;/* nice yellow */ - font-weight:normal; + padding: 3px 5px 3px 5px; + background-color: #fff380; /* nice yellow */ + font-weight: normal; -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; } + .tight { - margin:0; - padding:0; + margin: 0; + padding: 0; } .list-table td { - vertical-align:top; + vertical-align: top; } p.comment { border-top: 1px dotted #ccccce; - margin:0; - font-size:11px; + margin: 0; + font-size: 11px; color: #444444; - padding:5px 0 5px 0; + padding: 5px 0 5px 0; } .delete-icon { - vertical-align:middle; - padding-left:3px; + vertical-align: middle; + padding-left: 3px; } + /* these need to go */ table.form-as-table .errorlist { display: block; - margin:0; - padding:0 0 0 5px; - text-align:left; - font-size:10px; - color:darkred; + margin: 0; + padding: 0 0 0 5px; + text-align: left; + font-size: 10px; + color: darkred; } + table.form-as-table input { display: inline; margin-left: 4px; } + table.form-as-table th { - vertical-align:bottom; - padding-bottom:4px; + vertical-align: bottom; + padding-bottom: 4px; } + .form-row-vertical { margin-top: 8px; display: block; } + .form-row-vertical label { - margin-bottom:3px; - display:block; + margin-bottom: 3px; + display: block; } + /* above stuff needs to go */ .text-align-right { text-align: center; } + ul.form-horizontal-rows { - list-style:none; - margin:0; + list-style: none; + margin: 0; } + ul.form-horizontal-rows li { - position:relative; - height:40px; + position: relative; + height: 40px; } + ul.form-horizontal-rows label { - display:inline-block; + display: inline-block; } + ul.form-horizontal-rows ul.errorlist { - list-style:none; - color:darkred; - font-size:10px; - line-height:10px; - position:absolute; - top:2px; - left:180px; - text-align:left; - margin:0; + list-style: none; + color: darkred; + font-size: 10px; + line-height: 10px; + position: absolute; + top: 2px; + left: 180px; + text-align: left; + margin: 0; } + ul.form-horizontal-rows ul.errorlist li { - height:10px; + height: 10px; } + ul.form-horizontal-rows label { - position:absolute; - left:0px; - bottom:6px; - margin:0px; + position: absolute; + left: 0px; + bottom: 6px; + margin: 0px; line-height: 12px; font-size: 12px; } + ul.form-horizontal-rows li input { - position:absolute; - bottom:0px; - left:180px; - margin:0px; + position: absolute; + bottom: 0px; + left: 180px; + margin: 0px; } + #emailpw-form li input { - left:170px; + left: 170px; } + #emailpw-form ul.errorlist { - left:170px; + left: 170px; } + #changepw-form li input { - left:150px; + left: 150px; } + #changepw-form ul.errorlist { - left:150px; + left: 150px; } + .narrow .summary { float: left; } + .narrow .summary .question-title { font-weight: bold; font-size: 120%; } + .user-profile-tool-links { - padding-bottom:10px; + padding-bottom: 10px; font-weight: bold; } + .post-controls { - float:left; - font-size:11px; - line-height:12px; - min-width:200px; - margin-bottom:5px; + float: left; + font-size: 11px; + line-height: 12px; + min-width: 200px; + margin-bottom: 5px; } + #question-controls .tags { - margin:0 0 3px 0; + margin: 0 0 3px 0; } + .post-update-info-container { float: right; - min-width:190px; + min-width: 190px; } + .post-update-info { - display:inline-block; - float:right; - width:190px; - margin-bottom:5px; + display: inline-block; + float: right; + width: 190px; + margin-bottom: 5px; } + .post-update-info p { - font-size:11px; - line-height:15px; - margin:0 0 4px 0; - padding:0; + font-size: 11px; + line-height: 15px; + margin: 0 0 4px 0; + padding: 0; } + .post-update-info img { float: left; width: 32px; margin: 4px 8px 0 0; } + .comments-container { - clear:both; + clear: both; } + .admin { - background-color:#fff380;/* nice yellow */ + background-color: #fff380; /* nice yellow */ border: 1px solid darkred; padding: 0 5px 0 5px; } + .admin p { margin-bottom: 3px; } + .admin #action_status { - text-align:center; - font-weight:bold; + text-align: center; + font-weight: bold; } + #tagSelector { padding-bottom: 2px; } + #hideIgnoredTagsControl { margin: 5px 0 0 0; } + #hideIgnoredTagsCb { margin: 0 2px 0 1px; } + #recaptcha_widget_div { - width:318px; - float:left; - clear:both; + width: 318px; + float: left; + clear: both; } + p.signup_p { margin: 20px 0px 0px 0px; } + .simple-subscribe-options ul { - list-style:none; - list-style-position:outside; - margin:0; + list-style: none; + list-style-position: outside; + margin: 0; } diff --git a/forum/skins/default/templates/index.html b/forum/skins/default/templates/index.html index 7fa189ae..5bbb192b 100644..100755 --- a/forum/skins/default/templates/index.html +++ b/forum/skins/default/templates/index.html @@ -1,164 +1,124 @@ -{% extends "base.html" %} -<!-- index.html --> -{% load i18n %} -{% load extra_tags %} -{% load humanize %} -{% load extra_filters %} -{% load smart_if %} -{% block title %}{% spaceless %}{% trans "Home" %}{% endspaceless %}{% endblock %} -{% block meta %}<meta name="keywords" content="{{ settings.APP_KEYWORDS }}" /> - <meta name="description" content="{{ settings.APP_DESCRIPTION }}" />{% endblock %} -{% block forejs %} - <script type="text/javascript"> - var tags = {{ tags_autocomplete|safe }}; - $().ready(function(){ - var tab_id = "{{ tab_id }}"; - $("#"+tab_id).attr('className',"on"); - $("#nav_questions").attr('className',"on"); - }); - </script> - <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script> - <script type='text/javascript' src='{% media "/media/js/com.cnprog.tag_selector.js" %}'></script> -{% endblock %} -{% block content %} -<div class="tabBar"> - <div class="headQuestions">{% trans "Questions" %}</div> - <div class="tabsA"> - <a id="latest" href="{% url questions %}?sort=latest" title="{% trans "last updated questions" %}" >{% trans "newest" %}</a> - <a id="hottest" href="{% url questions %}?sort=hottest" title="{% trans "hottest questions" %}" >{% trans "hottest" %}</a> - <a id="mostvoted" href="{% url questions %}?sort=mostvoted" title="{% trans "most voted questions" %}" >{% trans "most voted" %}</a> - <a id="all" href="{% url questions %}" title="{% trans "all questions" %}" >{% trans "all questions" %}</a> - </div> -</div> -<!-- 问题列表 --> -<div id="listA"> - {% for question in questions %} - <div class="qstA"> - <h2> - <a href="{{ question.get_absolute_url }}">{{ question.get_question_title }}</a> - </h2> - <div class="stat"> - <table> - <tr> - <td><span class="num">{{ question.answer_count|intcomma }}</span> </td> - <td><span class="num">{{ question.score|intcomma }}</span> </td> - <td><span class="num">{{ question.view_count|cnprog_intword|safe }}</span> </td> - </tr> - <tr> - <td><span class="unit">{% trans "answers" %}</span></td> - <td><span class="unit">{% trans "votes" %}</span></td> - <td><span class="unit">{% trans "views" %}</span></td> - </tr> - </table> - </div> - - <div class="summary"> - {{ question.summary }}... - </div> - - {% ifequal tab_id 'active'%} - {% if question.wiki and settings.WIKI_ON %} - <span class="from wiki">{% trans "community wiki" %}</span> - <span class="date" title="{{ question.added_at }}">{% diff_date question.added_at %}</span> - {% else %} - <div class="from"> - {% comment %}{% gravatar question.last_activity_by 24 %}{% endcomment %} - <span class="author"><a href="{{ question.last_activity_by.get_profile_url }}">{{ question.last_activity_by }}</a></span> - <span class="score">{% get_score_badge question.last_activity_by %} </span> - <span class="date" title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</span> - </div> - {% endif %} - {% else %} - {% if question.wiki and settings.WIKI_ON %} - <span class="from wiki">{% trans "community wiki" %}</span> - <span class="date" title="{{ question.added_at }}">{% diff_date question.added_at %}</span> - {% else %} - <div class="from"> - {% comment %}{% gravatar question.author 24 %}{% endcomment %} - {% if question.last_activity_at != question.added_at %} - {% if question.author.id != question.last_activity_by.id %} - {% trans "Posted:" %} - <span class="author"><a href="{{ question.author.get_profile_url }}">{{ question.author }}</a></span> - <span class="score">{% get_score_badge question.author %} </span> - / {% trans "Updated:" %} - <span class="author"><a href="{{ question.last_activity_by.get_profile_url }}">{{ question.last_activity_by }}</a></span> - <span class="score">{% get_score_badge question.last_activity_by %} </span> - <span class="date" title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</span> - {% else %} - {% trans "Updated:" %} - <span class="author"><a href="{{ question.last_activity_by.get_profile_url }}">{{ question.last_activity_by }}</a></span> - <span class="score">{% get_score_badge question.last_activity_by %} </span> - <span class="date" title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</span> - {% endif %} - {% else %} - {% trans "Posted:" %} - <span class="author"><a href="{{ question.author.get_profile_url }}">{{ question.author }}</a></span> - <span class="score">{% get_score_badge question.author %} </span> - <span class="date" title="{{ question.added_at }}">{% diff_date question.added_at %}</span> - {% endif %} - </div> - {% endif %} - {% endifequal %} - - <div class="tags"> - {% for tag in question.tagname_list %} - <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a> - {% endfor %} - </div> - </div> - {% endfor %} -</div> -{% endblock %} - -{% block sidebar %} -{% if not request.user.is_authenticated %} -<div class="boxA"> - <h3>{% trans "welcome to website" %}</h3> - <div class="body"> - {{ settings.APP_INTRO|safe }} - <div class="more"><a href="{% url about %}">{% trans "about" %} »</a></div> - <div class="more"><a href="{% url faq %}">{% trans "faq" %} »</a></div> - </div> -</div> -{% else %} -{% include "tag_selector.html" %} -{% endif %} -<div class="boxC"> - <h3>{% trans "Recent tags" %}</h3> - <div class="body"> - <div class="tags"> - {% for tag in tags %} - <a rel="tag" - title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a> - {% endfor %} - </div> - <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} »</a> </div> - </div> -</div> -{% if awards %} -<div class="boxC"> - <h3>{% trans "Recent awards" %}</h3> - <div class="body"> - <ul class="badge-list"> - {% for award in awards %} - <li> - <a href="{% url badges %}{{award.badge_id}}/{{award.badge_name}}" title="{{ award.badge_description }}" class="medal"> - <span class="badge{{ award.badge_type }}">●</span> {{ award.badge_name }}</a> {% trans "given to" %} - <a href="{% url users %}{{award.user_id}}/{{award.user_name}}">{{ award.user_name }}</a> - </li> - {% endfor %} - </ul> - <div class="more"><a href="{% url badges %}">{% trans "all awards" %} »</a> </div> - </div> -</div> -{% endif %} -<div id="feeds"> -<a href="{% media "/feeds/rss" %}" title="{% trans "subscribe to last 30 questions by RSS" %}">{% trans "subscribe to the questions feed" %}</a> -</div> -{% endblock %} -{% block tail %} -<div style="padding:5px 0 5px 5px;"> -<span class="evenMore">{% trans "Still looking for more? See" %} <a href="{% url questions %}">{% trans "complete list of questions" %}</a> {% trans "or" %} <a href="{% url tags %}">{% trans "popular tags" %}</a>{% trans "." %} {% trans "Please help us answer" %} <a href="{% url questions %}unanswered">{% trans "list of unanswered questions" %}</a>{% trans "." %}</span> -</div> -{% endblock %} -<!-- index.html --> +{% extends "base.html" %}
+<!-- index.html -->
+{% load i18n %}
+{% load extra_tags %}
+{% load humanize %}
+{% load extra_filters %}
+{% load smart_if %}
+{% block title %}{% spaceless %}{% trans "Home" %}{% endspaceless %}{% endblock %}
+{% block meta %}<meta name="keywords" content="{{ settings.APP_KEYWORDS }}" />
+ <meta name="description" content="{{ settings.APP_DESCRIPTION }}" />{% endblock %}
+{% block forejs %}
+ <script type="text/javascript">
+ var tags = {{ tags_autocomplete|safe }};
+ $().ready(function(){
+ var tab_id = "{{ tab_id }}";
+ $("#"+tab_id).attr('className',"on");
+ $("#nav_questions").attr('className',"on");
+ });
+ </script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.tag_selector.js" %}'></script>
+{% endblock %}
+{% block content %}
+<div class="tabBar">
+ <div class="headQuestions">{% trans "Questions" %}</div>
+ <div class="tabsA">
+ <a id="latest" href="{% url questions %}?sort=latest" title="{% trans "last updated questions" %}" >{% trans "newest" %}</a>
+ <a id="hottest" href="{% url questions %}?sort=hottest" title="{% trans "hottest questions" %}" >{% trans "hottest" %}</a>
+ <a id="mostvoted" href="{% url questions %}?sort=mostvoted" title="{% trans "most voted questions" %}" >{% trans "most voted" %}</a>
+ <a id="all" href="{% url questions %}" title="{% trans "all questions" %}" >{% trans "all questions" %}</a>
+ </div>
+</div>
+<!-- ???? -->
+<div id="listA">
+ {% for question in questions.object_list %}
+ <div class="short-summary">
+ <div class="counts">
+ <div class="votes">
+ <div class="item-count">{{question.score|intcomma}}</div>
+ <div>{% trans "votes" %}</div>
+ </div >
+ <div {% if question.answer_accepted %}title="{% trans "this answer has been accepted to be correct" %}"{% endif %} class="status {% if question.answer_accepted %}answered-accepted{% endif %} {% ifequal question.answer_count 0 %}unanswered{% endifequal %}{% ifnotequal question.answer_count 0 %}answered{% endifnotequal %}">
+ <div class="item-count">{{question.answer_count|intcomma}}</div>
+ <div>{% trans "answers" %}</div>
+ </div>
+ <div class="views">
+ <div class="item-count">{{question.view_count|cnprog_intword|safe}}</div>
+ <div>{% trans "views" %}</div>
+ </div>
+ </div>
+
+ <h2><a title="{{question.summary}}" href="{% url question id=question.id %}{{question.title|slugify}}">{{question.title}}</a></h2>
+
+ <div class="userinfo">
+ <span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>
+ {% if question.last_activity_by %}
+ <a href="{{ question.last_activity_by.get_profile_url }}">{{ question.last_activity_by }}</a> {% get_score_badge question.last_activity_by %}
+ {% endif %}
+ </div>
+
+ <div class="tags">
+ {% for tag in question.tagname_list %}
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ {% endfor %}
+ </div>
+ </div>
+ {% endfor %}
+</div>
+{% endblock %}
+
+{% block sidebar %}
+{% if not request.user.is_authenticated %}
+<div class="boxA">
+ <h3>{% trans "welcome to website" %}</h3>
+ <div class="body">
+ {{ settings.APP_INTRO|safe }}
+ <div class="more"><a href="{% url about %}">{% trans "about" %} </a></div>
+ <div class="more"><a href="{% url faq %}">{% trans "faq" %} </a></div>
+ </div>
+</div>
+{% else %}
+{% include "tag_selector.html" %}
+{% endif %}
+<div class="boxC">
+ <h3>{% trans "Recent tags" %}</h3>
+ <div class="body">
+ <div class="tags">
+ {% for tag in tags %}
+ <a rel="tag"
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ {% endfor %}
+ </div>
+ <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} </a> </div>
+ </div>
+</div>
+{% if awards %}
+<div class="boxC">
+ <h3>{% trans "Recent awards" %}</h3>
+ <div class="body">
+ <ul class="badge-list">
+ {% for award in awards %}
+ <li>
+ <a href="{% url badges %}{{award.badge_id}}/{{award.badge_name}}" title="{{ award.badge_description }}" class="medal">
+ <span class="badge{{ award.badge_type }}">●</span> {{ award.badge_name }}</a> {% trans "given to" %}
+ <a href="{% url users %}{{award.user_id}}/{{award.user_name}}">{{ award.user_name }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ <div class="more"><a href="{% url badges %}">{% trans "all awards" %} </a> </div>
+ </div>
+</div>
+{% endif %}
+<div id="feeds">
+<a href="{% media "/feeds/rss" %}" title="{% trans "subscribe to last 30 questions by RSS" %}">{% trans "subscribe to the questions feed" %}</a>
+</div>
+{% endblock %}
+{% block tail %}
+<div class="pager">{% cnprog_paginator context %}</div>
+ <div class="pagesize">{% cnprog_pagesize context %}</div>
+<!-- <div style="padding:5px 0 5px 5px;">
+<span class="evenMore">{% trans "Still looking for more? See" %} <a href="{% url questions %}">{% trans "complete list of questions" %}</a> {% trans "or" %} <a href="{% url tags %}">{% trans "popular tags" %}</a>{% trans "." %} {% trans "Please help us answer" %} <a href="{% url questions %}unanswered">{% trans "list of unanswered questions" %}</a>{% trans "." %}</span>
+</div> -->
+{% endblock %}
+<!-- index.html -->
\ No newline at end of file diff --git a/forum/skins/default/templates/index_.html b/forum/skins/default/templates/index_.html new file mode 100755 index 00000000..5e4cf533 --- /dev/null +++ b/forum/skins/default/templates/index_.html @@ -0,0 +1,124 @@ +{% extends "base.html" %}
+<!-- index.html -->
+{% load i18n %}
+{% load extra_tags %}
+{% load humanize %}
+{% load extra_filters %}
+{% load smart_if %}
+{% block title %}{% spaceless %}{% trans "Home" %}{% endspaceless %}{% endblock %}
+{% block meta %}<meta name="keywords" content="{{ settings.APP_KEYWORDS }}" />
+ <meta name="description" content="{{ settings.APP_DESCRIPTION }}" />{% endblock %}
+{% block forejs %}
+ <script type="text/javascript">
+ var tags = {{ tags_autocomplete|safe }};
+ $().ready(function(){
+ var tab_id = "{{ tab_id }}";
+ $("#"+tab_id).attr('className',"on");
+ $("#nav_questions").attr('className',"on");
+ });
+ </script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.tag_selector.js" %}'></script>
+{% endblock %}
+{% block content %}
+<div class="tabBar">
+ <div class="headQuestions">{% trans "Questions" %}</div>
+ <div class="tabsA">
+ <a id="latest" href="{% url index %}?sort=latest" title="{% trans "last updated questions" %}" >{% trans "newest" %}</a>
+ <a id="hottest" href="{% url index %}?sort=hottest" title="{% trans "hottest questions" %}" >{% trans "hottest" %}</a>
+ <a id="mostvoted" href="{% url index %}?sort=mostvoted" title="{% trans "most voted questions" %}" >{% trans "most voted" %}</a>
+ <a id="all" href="{% url index %}" title="{% trans "all questions" %}" >{% trans "all questions" %}</a>
+ </div>
+</div>
+
+<div id="listA">
+ {% for question in questions.object_list %}
+ <div class="short-summary">
+ <div class="counts">
+ <div class="votes">
+ <div class="item-count">{{question.score|intcomma}}</div>
+ <div>{% trans "votes" %}</div>
+ </div >
+ <div {% if question.answer_accepted %}title="{% trans "this answer has been accepted to be correct" %}"{% endif %} class="status {% if question.answer_accepted %}answered-accepted{% endif %} {% ifequal question.answer_count 0 %}unanswered{% endifequal %}{% ifnotequal question.answer_count 0 %}answered{% endifnotequal %}">
+ <div class="item-count">{{question.answer_count|intcomma}}</div>
+ <div>{% trans "answers" %}</div>
+ </div>
+ <div class="views">
+ <div class="item-count">{{question.view_count|cnprog_intword|safe}}</div>
+ <div>{% trans "views" %}</div>
+ </div>
+ </div>
+
+ <h2><a title="{{question.summary}}" href="{% url question id=question.id %}{{question.title|slugify}}">{{question.title}}</a></h2>
+
+ <div class="userinfo">
+ <span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>
+ {% if question.last_activity_by %}
+ <a href="{{ question.last_activity_by.get_profile_url }}">{{ question.last_activity_by }}</a> {% get_score_badge question.last_activity_by %}
+ {% endif %}
+ </div>
+
+ <div class="tags">
+ {% for tag in question.tagname_list %}
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ {% endfor %}
+ </div>
+ </div>
+ {% endfor %}
+</div>
+{% endblock %}
+
+{% block sidebar %}
+{% if not request.user.is_authenticated %}
+<div class="boxA">
+ <h3>{% trans "welcome to website" %}</h3>
+ <div class="body">
+ {{ settings.APP_INTRO|safe }}
+ <div class="more"><a href="{% url about %}">{% trans "about" %} »</a></div>
+ <div class="more"><a href="{% url faq %}">{% trans "faq" %} »</a></div>
+ </div>
+</div>
+{% else %}
+{% include "tag_selector.html" %}
+{% endif %}
+<div class="boxC">
+ <h3>{% trans "Recent tags" %}</h3>
+ <div class="body">
+ <div class="tags">
+ {% for tag in tags %}
+ <a rel="tag"
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ {% endfor %}
+ </div>
+ <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} »</a> </div>
+ </div>
+</div>
+{% if awards %}
+<div class="boxC">
+ <h3>{% trans "Recent awards" %}</h3>
+ <div class="body">
+ <ul class="badge-list">
+ {% for award in awards %}
+ <li>
+ <a href="{% url badges %}{{award.badge_id}}/{{award.badge_name}}" title="{{ award.badge_description }}" class="medal">
+ <span class="badge{{ award.badge_type }}">●</span> {{ award.badge_name }}</a>
+ <a href="{% url users %}{{award.user_id}}/{{award.user_name}}">{{ award.user_name }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ <div class="more"><a href="{% url badges %}">{% trans "all awards" %} »</a> </div>
+ </div>
+</div>
+{% endif %}
+<div id="feeds">
+<a href="{% media "/feeds/rss" %}" title="{% trans "subscribe to last 30 questions by RSS" %}">{% trans "subscribe to the questions feed" %}</a>
+</div>
+{% endblock %}
+{% block tail %}
+<div class="pager">{% cnprog_paginator context %}</div>
+ <div class="pagesize">{% cnprog_pagesize context %}</div>
+<!-- <div style="padding:5px 0 5px 5px;">
+<span class="evenMore">{% trans "Still looking for more? See" %} <a href="{% url questions %}">{% trans "complete list of questions" %}</a> {% trans "or" %} <a href="{% url tags %}">{% trans "popular tags" %}</a>{% trans "." %} {% trans "Please help us answer" %} <a href="{% url questions %}unanswered">{% trans "list of unanswered questions" %}</a>{% trans "." %}</span>
+</div> -->
+{% endblock %}
+<!-- index.html -->
diff --git a/forum/urls.py b/forum/urls.py index 219364cb..fd9ebdc1 100644 --- a/forum/urls.py +++ b/forum/urls.py @@ -84,12 +84,19 @@ urlpatterns = patterns('', url(r'^%s(.*)' % _('nimda/'), admin.site.root, name='osqa_admin'), url(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}, name='feeds'), url(r'^%s$' % _('upload/'), app.writers.upload, name='upload'), - #url(r'^%s$' % _('books/'), app.books.books, name='books'), - #url(r'^%s%s(?P<short_name>[^/]+)/$' % (_('books/'), _('ask/')), app.books.ask_book, name='ask_book'), - #url(r'^%s(?P<short_name>[^/]+)/$' % _('books/'), app.books.book, name='book'), url(r'^%s$' % _('search/'), app.readers.search, name='search'), url(r'^%s$' % _('feedback/'), app.meta.feedback, name='feedback'), (r'^%sfb/' % _('account/'), include('fbconnect.urls')), (r'^%s' % _('account/'), include('django_authopenid.urls')), (r'^i18n/', include('django.conf.urls.i18n')), ) + +from forum.modules import get_modules_script + +module_patterns = get_modules_script('urls') + +for pattern_file in module_patterns: + pattern = getattr(pattern_file, 'urlpatterns', None) + if pattern: + urlpatterns += pattern + diff --git a/forum/views/__init__.py b/forum/views/__init__.py index faea1179..291fee2a 100644 --- a/forum/views/__init__.py +++ b/forum/views/__init__.py @@ -3,4 +3,3 @@ import writers import commands import users import meta -#import books diff --git a/forum/views/meta.py b/forum/views/meta.py index 164c056a..b4c7a37f 100644 --- a/forum/views/meta.py +++ b/forum/views/meta.py @@ -61,8 +61,8 @@ def badges(request):#user status/reputation system badges = Badge.objects.all().order_by('type') my_badges = [] if request.user.is_authenticated(): - my_badges = Award.objects.filter(user=request.user) - my_badges.query.group_by = ['badge_id'] + my_badges = Award.objects.filter(user=request.user).values('badge_id') + #my_badges.query.group_by = ['badge_id'] return render_to_response('badges.html', { 'badges' : badges, diff --git a/forum/views/readers.py b/forum/views/readers.py index 72378218..6b0da476 100644 --- a/forum/views/readers.py +++ b/forum/views/readers.py @@ -28,13 +28,13 @@ from forum.utils.forms import get_next_url # used in index page #refactor - move these numbers somewhere? -INDEX_PAGE_SIZE = 20 +INDEX_PAGE_SIZE = 30 INDEX_AWARD_SIZE = 15 -INDEX_TAGS_SIZE = 100 +INDEX_TAGS_SIZE = 25 # used in tags list DEFAULT_PAGE_SIZE = 60 # used in questions -QUESTIONS_PAGE_SIZE = 10 +QUESTIONS_PAGE_SIZE = 30 # used in answers ANSWERS_PAGE_SIZE = 10 @@ -87,10 +87,19 @@ def index(request):#generates front page - shows listing of questions sorted in } view_id, orderby = _get_and_remember_questions_sort_method(request, view_dic, 'latest') - page_size = request.session.get('pagesize', QUESTIONS_PAGE_SIZE) - questions = Question.objects.exclude(deleted=True).order_by(orderby)[:page_size] + pagesize = request.session.get("pagesize",QUESTIONS_PAGE_SIZE) + try: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + + qs = Question.objects.exclude(deleted=True).order_by(orderby) + + objects_list = Paginator(qs, pagesize) + questions = objects_list.page(page) + # RISK - inner join queries - questions = questions.select_related() + #questions = questions.select_related() tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE) awards = Award.objects.get_recent_awards() @@ -111,7 +120,17 @@ def index(request):#generates front page - shows listing of questions sorted in "tab_id" : view_id, "tags" : tags, "awards" : awards[:INDEX_AWARD_SIZE], - }, context_instance=RequestContext(request)) + "context" : { + 'is_paginated' : True, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': questions.has_previous(), + 'has_next': questions.has_next(), + 'previous': questions.previous_page_number(), + 'next': questions.next_page_number(), + 'base_url' : request.path + '?sort=%s&' % view_id, + 'pagesize' : pagesize + }}, context_instance=RequestContext(request)) def unanswered(request):#generates listing of unanswered questions return questions(request, unanswered=True) @@ -126,7 +145,7 @@ def questions(request, tagname=None, unanswered=False):#a view generating listin # Set flag to False by default. If it is equal to True, then need to be saved. pagesize_changed = False # get pagesize from session, if failed then get default value - pagesize = request.session.get("pagesize",10) + pagesize = request.session.get("pagesize",QUESTIONS_PAGE_SIZE) try: page = int(request.GET.get('page', '1')) except ValueError: @@ -287,25 +306,16 @@ def search(request): #generates listing of questions matching a search query - i view_id = "latest" orderby = "-added_at" - if settings.USE_PG_FTS: - objects = Question.objects.filter(deleted=False).extra( - select={ - 'ranking': "ts_rank_cd(tsv, plainto_tsquery(%s), 32)", - }, - where=["tsv @@ plainto_tsquery(%s)"], - params=[keywords], - select_params=[keywords] - ).order_by('-ranking') - - elif settings.USE_SPHINX_SEARCH == True: - #search index is now free of delete questions and answers - #so there is not "antideleted" filtering here - objects = Question.search.query(keywords) - #no related selection either because we're relying on full text search here - else: + def question_search(keywords, orderby): objects = Question.objects.filter(deleted=False).extra(where=['title like %s'], params=['%' + keywords + '%']).order_by(orderby) # RISK - inner join queries - objects = objects.select_related(); + return objects.select_related(); + + from forum.modules import get_handler + + question_search = get_handler('question_search', question_search) + + objects = question_search(keywords, orderby) objects_list = Paginator(objects, pagesize) questions = objects_list.page(page) diff --git a/forum/views/users.py b/forum/views/users.py index 517bb170..04ffb690 100644 --- a/forum/views/users.py +++ b/forum/views/users.py @@ -1,6 +1,7 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.core.paginator import Paginator, EmptyPage, InvalidPage +from django.template.defaultfilters import slugify from django.contrib.contenttypes.models import ContentType from django.core.urlresolvers import reverse from django.shortcuts import render_to_response, get_object_or_404 diff --git a/pgfulltext/__init__.py b/forum_modules/__init__.py index e69de29b..e69de29b 100644..100755 --- a/pgfulltext/__init__.py +++ b/forum_modules/__init__.py diff --git a/forum_modules/books/__init__.py b/forum_modules/books/__init__.py new file mode 100755 index 00000000..bdd27b2b --- /dev/null +++ b/forum_modules/books/__init__.py @@ -0,0 +1,3 @@ +NAME = 'Osqa Books'
+DESCRIPTION = "Allows discussion around books."
+CAN_ENABLE = True
diff --git a/forum_modules/books/models.py b/forum_modules/books/models.py new file mode 100755 index 00000000..ecde34b3 --- /dev/null +++ b/forum_modules/books/models.py @@ -0,0 +1,63 @@ +from django.db import models
+from django.contrib.auth.models import User
+from forum.models import Question
+from django.core.urlresolvers import reverse
+from django.utils.http import urlquote as django_urlquote
+from django.template.defaultfilters import slugify
+
+class Book(models.Model):
+ """
+ Model for book info
+ """
+ user = models.ForeignKey(User)
+ title = models.CharField(max_length=255)
+ short_name = models.CharField(max_length=255)
+ author = models.CharField(max_length=255)
+ price = models.DecimalField(max_digits=6, decimal_places=2)
+ pages = models.SmallIntegerField()
+ published_at = models.DateTimeField()
+ publication = models.CharField(max_length=255)
+ cover_img = models.CharField(max_length=255)
+ tagnames = models.CharField(max_length=125)
+ added_at = models.DateTimeField()
+ last_edited_at = models.DateTimeField()
+ questions = models.ManyToManyField(Question, related_name='book', db_table='book_question')
+
+ def get_absolute_url(self):
+ return reverse('book', args=[django_urlquote(slugify(self.short_name))])
+
+ def __unicode__(self):
+ return self.title
+
+ class Meta:
+ app_label = 'forum'
+ db_table = u'book'
+
+class BookAuthorInfo(models.Model):
+ """
+ Model for book author info
+ """
+ user = models.ForeignKey(User)
+ book = models.ForeignKey(Book)
+ blog_url = models.CharField(max_length=255)
+ added_at = models.DateTimeField()
+ last_edited_at = models.DateTimeField()
+
+ class Meta:
+ app_label = 'forum'
+ db_table = u'book_author_info'
+
+class BookAuthorRss(models.Model):
+ """
+ Model for book author blog rss
+ """
+ user = models.ForeignKey(User)
+ book = models.ForeignKey(Book)
+ title = models.CharField(max_length=255)
+ url = models.CharField(max_length=255)
+ rss_created_at = models.DateTimeField()
+ added_at = models.DateTimeField()
+
+ class Meta:
+ app_label = 'forum'
+ db_table = u'book_author_rss'
\ No newline at end of file diff --git a/forum_modules/books/urls.py b/forum_modules/books/urls.py new file mode 100755 index 00000000..0e0432ba --- /dev/null +++ b/forum_modules/books/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls.defaults import *
+from django.utils.translation import ugettext as _
+
+import views as app
+
+urlpatterns = patterns('',
+ url(r'^%s$' % _('books/'), app.books, name='books'),
+ url(r'^%s%s(?P<short_name>[^/]+)/$' % (_('books/'), _('ask/')), app.ask_book, name='ask_book'),
+ url(r'^%s(?P<short_name>[^/]+)/$' % _('books/'), app.book, name='book'),
+)
\ No newline at end of file diff --git a/forum/views/books.py b/forum_modules/books/views.py index bb2ada6a..31c82971 100644..100755 --- a/forum/views/books.py +++ b/forum_modules/books/views.py @@ -1,140 +1,142 @@ -from django.contrib.auth.decorators import login_required -from django.core.urlresolvers import reverse -from django.shortcuts import render_to_response -from forum.models import BookAuthorInfo, BookAuthorRss, Book -from forum.models import Question, QuestionRevision -from django.core.urlresolvers import reverse -from django.http import HttpResponseRedirect - -def books(request): - """this view seems to redirect to a default book - maybe it should instead show some popular titles? - """ - return HttpResponseRedirect(reverse('books') + 'mysql-zhaoyang') - -def book(request, short_name, unanswered=False): - """ - 1. questions list - 2. book info - 3. author info and blog rss items - """ - """ - List of Questions, Tagged questions, and Unanswered questions. - """ - books = Book.objects.extra(where=['short_name = %s'], params=[short_name]) - match_count = len(books) - if match_count == 0: - raise Http404 - else: - # the book info - book = books[0] - # get author info - author_info = BookAuthorInfo.objects.get(book=book) - # get author rss info - author_rss = BookAuthorRss.objects.filter(book=book) - - # get pagesize from session, if failed then get default value - user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE) - # set pagesize equal to logon user specified value in database - if request.user.is_authenticated() and request.user.questions_per_page > 0: - user_page_size = request.user.questions_per_page - - try: - page = int(request.GET.get('page', '1')) - except ValueError: - page = 1 - - view_id = request.GET.get('sort', None) - view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" } - try: - orderby = view_dic[view_id] - except KeyError: - view_id = "latest" - orderby = "-added_at" - - # check if request is from tagged questions - if unanswered: - # check if request is from unanswered questions - # Article.objects.filter(publications__id__exact=1) - objects = Question.objects.filter(book__id__exact=book.id, deleted=False, answer_count=0).order_by(orderby) - else: - objects = Question.objects.filter(book__id__exact=book.id, deleted=False).order_by(orderby) - - # RISK - inner join queries - objects = objects.select_related(); - objects_list = Paginator(objects, user_page_size) - questions = objects_list.page(page) - - return render_to_response('book.html', { - "book" : book, - "author_info" : author_info, - "author_rss" : author_rss, - "questions" : questions, - "context" : { - 'is_paginated' : True, - 'pages': objects_list.num_pages, - 'page': page, - 'has_previous': questions.has_previous(), - 'has_next': questions.has_next(), - 'previous': questions.previous_page_number(), - 'next': questions.next_page_number(), - 'base_url' : request.path + '?sort=%s&' % view_id, - 'pagesize' : user_page_size - } - }, context_instance=RequestContext(request)) - -@login_required -def ask_book(request, short_name): - if request.method == "POST": - form = AskForm(request.POST) - if form.is_valid(): - added_at = datetime.datetime.now() - html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) - question = Question( - title = strip_tags(form.cleaned_data['title']), - author = request.user, - added_at = added_at, - last_activity_at = added_at, - last_activity_by = request.user, - wiki = form.cleaned_data['wiki'], - tagnames = form.cleaned_data['tags'].strip(), - html = html, - summary = strip_tags(html)[:120] - ) - if question.wiki: - question.last_edited_by = question.author - question.last_edited_at = added_at - question.wikified_at = added_at - - question.save() - - # create the first revision - QuestionRevision.objects.create( - question = question, - revision = 1, - title = question.title, - author = request.user, - revised_at = added_at, - tagnames = question.tagnames, - summary = CONST['default_version'], - text = form.cleaned_data['text'] - ) - - books = Book.objects.extra(where=['short_name = %s'], params=[short_name]) - match_count = len(books) - if match_count == 1: - # the book info - book = books[0] - book.questions.add(question) - - return HttpResponseRedirect(question.get_absolute_url()) - else: - form = AskForm() - - tags = _get_tags_cache_json() - return render_to_response('ask.html', { - 'form' : form, - 'tags' : tags, - 'email_validation_faq_url': reverse('faq') + '#validate', - }, context_instance=RequestContext(request)) - +from django.shortcuts import render_to_response, get_object_or_404
+from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404
+from django.template import RequestContext
+from django.contrib.auth.decorators import login_required
+from django.core.urlresolvers import reverse
+from django.utils.html import *
+
+from models import *
+
+from forum.forms import AskForm
+from forum.views.readers import _get_tags_cache_json
+from forum.models import *
+from forum.utils.html import sanitize_html
+
+def books(request):
+ return HttpResponseRedirect(reverse('books') + '/mysql-zhaoyang')
+
+def book(request, short_name, unanswered=False):
+ """
+ 1. questions list
+ 2. book info
+ 3. author info and blog rss items
+ """
+ """
+ List of Questions, Tagged questions, and Unanswered questions.
+ """
+ books = Book.objects.extra(where=['short_name = %s'], params=[short_name])
+ match_count = len(books)
+ if match_count == 0:
+ raise Http404
+ else:
+ # the book info
+ book = books[0]
+ # get author info
+ author_info = BookAuthorInfo.objects.get(book=book)
+ # get author rss info
+ author_rss = BookAuthorRss.objects.filter(book=book)
+
+ # get pagesize from session, if failed then get default value
+ user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
+ # set pagesize equal to logon user specified value in database
+ if request.user.is_authenticated() and request.user.questions_per_page > 0:
+ user_page_size = request.user.questions_per_page
+
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ view_id = request.GET.get('sort', None)
+ view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
+ try:
+ orderby = view_dic[view_id]
+ except KeyError:
+ view_id = "latest"
+ orderby = "-added_at"
+
+ # check if request is from tagged questions
+ if unanswered:
+ # check if request is from unanswered questions
+ # Article.objects.filter(publications__id__exact=1)
+ objects = Question.objects.filter(book__id__exact=book.id, deleted=False, answer_count=0).order_by(orderby)
+ else:
+ objects = Question.objects.filter(book__id__exact=book.id, deleted=False).order_by(orderby)
+
+ # RISK - inner join queries
+ objects = objects.select_related();
+ objects_list = Paginator(objects, user_page_size)
+ questions = objects_list.page(page)
+
+ return render_to_response('book.html', {
+ "book" : book,
+ "author_info" : author_info,
+ "author_rss" : author_rss,
+ "questions" : questions,
+ "context" : {
+ 'is_paginated' : True,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': questions.has_previous(),
+ 'has_next': questions.has_next(),
+ 'previous': questions.previous_page_number(),
+ 'next': questions.next_page_number(),
+ 'base_url' : request.path + '?sort=%s&' % view_id,
+ 'pagesize' : user_page_size
+ }
+ }, context_instance=RequestContext(request))
+
+@login_required
+def ask_book(request, short_name):
+ if request.method == "POST":
+ form = AskForm(request.POST)
+ if form.is_valid():
+ added_at = datetime.datetime.now()
+ html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
+ question = Question(
+ title = strip_tags(form.cleaned_data['title']),
+ author = request.user,
+ added_at = added_at,
+ last_activity_at = added_at,
+ last_activity_by = request.user,
+ wiki = form.cleaned_data['wiki'],
+ tagnames = form.cleaned_data['tags'].strip(),
+ html = html,
+ summary = strip_tags(html)[:120]
+ )
+ if question.wiki:
+ question.last_edited_by = question.author
+ question.last_edited_at = added_at
+ question.wikified_at = added_at
+
+ question.save()
+
+ # create the first revision
+ QuestionRevision.objects.create(
+ question = question,
+ revision = 1,
+ title = question.title,
+ author = request.user,
+ revised_at = added_at,
+ tagnames = question.tagnames,
+ summary = CONST['default_version'],
+ text = form.cleaned_data['text']
+ )
+
+ books = Book.objects.extra(where=['short_name = %s'], params=[short_name])
+ match_count = len(books)
+ if match_count == 1:
+ # the book info
+ book = books[0]
+ book.questions.add(question)
+
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+ form = AskForm()
+
+ tags = _get_tags_cache_json()
+ return render_to_response('ask.html', {
+ 'form' : form,
+ 'tags' : tags,
+ 'email_validation_faq_url': reverse('faq') + '#validate',
+ }, context_instance=RequestContext(request))
\ No newline at end of file diff --git a/forum_modules/pgfulltext/__init__.py b/forum_modules/pgfulltext/__init__.py new file mode 100755 index 00000000..ec4892c7 --- /dev/null +++ b/forum_modules/pgfulltext/__init__.py @@ -0,0 +1,9 @@ +NAME = 'Postgresql Full Text Search'
+DESCRIPTION = "Enables PostgreSql full text search functionality."
+
+try:
+ import psycopg2
+ CAN_ENABLE = True
+except:
+ CAN_ENABLE = False
+
\ No newline at end of file diff --git a/forum_modules/pgfulltext/handlers.py b/forum_modules/pgfulltext/handlers.py new file mode 100755 index 00000000..17fb1762 --- /dev/null +++ b/forum_modules/pgfulltext/handlers.py @@ -0,0 +1,11 @@ +from forum.models import Question
+
+def question_search(keywords, orderby):
+ return Question.objects.filter(deleted=False).extra(
+ select={
+ 'ranking': "ts_rank_cd(tsv, plainto_tsquery(%s), 32)",
+ },
+ where=["tsv @@ plainto_tsquery(%s)"],
+ params=[keywords],
+ select_params=[keywords]
+ ).order_by(orderby, '-ranking')
\ No newline at end of file diff --git a/forum_modules/pgfulltext/management.py b/forum_modules/pgfulltext/management.py new file mode 100755 index 00000000..89eb1395 --- /dev/null +++ b/forum_modules/pgfulltext/management.py @@ -0,0 +1,29 @@ +import os
+
+from django.db import connection, transaction
+from django.conf import settings
+
+import forum.models
+
+if settings.DATABASE_ENGINE in ('postgresql_psycopg2', 'postgresql', ):
+ from django.db.models.signals import post_syncdb
+
+ def setup_pgfulltext(sender, **kwargs):
+ if sender == forum.models:
+ install_pg_fts()
+
+ post_syncdb.connect(setup_pgfulltext)
+
+def install_pg_fts():
+ f = open(os.path.join(os.path.dirname(__file__), 'pg_fts_install.sql'), 'r')
+
+ try:
+ cursor = connection.cursor()
+ cursor.execute(f.read())
+ transaction.commit_unless_managed()
+ except:
+ pass
+ finally:
+ cursor.close()
+
+ f.close()
diff --git a/forum_modules/pgfulltext/pg_fts_install.sql b/forum_modules/pgfulltext/pg_fts_install.sql new file mode 100755 index 00000000..72eca516 --- /dev/null +++ b/forum_modules/pgfulltext/pg_fts_install.sql @@ -0,0 +1,38 @@ +ALTER TABLE question ADD COLUMN tsv tsvector;
+
+CREATE OR REPLACE FUNCTION public.create_plpgsql_language ()
+ RETURNS TEXT
+ AS $$
+ CREATE LANGUAGE plpgsql;
+ SELECT 'language plpgsql created'::TEXT;
+ $$
+LANGUAGE 'sql';
+
+SELECT CASE WHEN
+ (SELECT true::BOOLEAN
+ FROM pg_language
+ WHERE lanname='plpgsql')
+ THEN
+ (SELECT 'language already installed'::TEXT)
+ ELSE
+ (SELECT public.create_plpgsql_language())
+ END;
+
+DROP FUNCTION public.create_plpgsql_language ();
+
+CREATE OR REPLACE FUNCTION set_question_tsv() RETURNS TRIGGER AS $$
+begin
+ new.tsv :=
+ setweight(to_tsvector('english', coalesce(new.tagnames,'')), 'A') ||
+ setweight(to_tsvector('english', coalesce(new.title,'')), 'B') ||
+ setweight(to_tsvector('english', coalesce(new.summary,'')), 'C');
+ RETURN new;
+end
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
+ON question FOR EACH ROW EXECUTE PROCEDURE set_question_tsv();
+
+ CREATE INDEX question_tsv ON question USING gin(tsv);
+
+UPDATE question SET title = title;
diff --git a/forum_modules/sphinxfulltext/DISABLED b/forum_modules/sphinxfulltext/DISABLED new file mode 100755 index 00000000..e69de29b --- /dev/null +++ b/forum_modules/sphinxfulltext/DISABLED diff --git a/forum_modules/sphinxfulltext/__init__.py b/forum_modules/sphinxfulltext/__init__.py new file mode 100755 index 00000000..e69de29b --- /dev/null +++ b/forum_modules/sphinxfulltext/__init__.py diff --git a/forum_modules/sphinxfulltext/dependencies.py b/forum_modules/sphinxfulltext/dependencies.py new file mode 100755 index 00000000..5ddb91d2 --- /dev/null +++ b/forum_modules/sphinxfulltext/dependencies.py @@ -0,0 +1,2 @@ +DJANGO_APPS = ('djangosphinx', )
+
diff --git a/forum_modules/sphinxfulltext/handlers.py b/forum_modules/sphinxfulltext/handlers.py new file mode 100755 index 00000000..665c9380 --- /dev/null +++ b/forum_modules/sphinxfulltext/handlers.py @@ -0,0 +1,4 @@ +from forum.models import Question
+
+def question_search(keywords, orderby):
+ return Question.search.query(keywords)
\ No newline at end of file diff --git a/forum_modules/sphinxfulltext/models.py b/forum_modules/sphinxfulltext/models.py new file mode 100755 index 00000000..66b8ddf9 --- /dev/null +++ b/forum_modules/sphinxfulltext/models.py @@ -0,0 +1,10 @@ +from forum.models import Question
+from django.conf import settings
+from djangosphinx.manager import SphinxSearch
+
+
+Question.add_to_class('search', SphinxSearch(
+ index=' '.join(settings.SPHINX_SEARCH_INDICES),
+ mode='SPH_MATCH_ALL',
+ )
+ )
diff --git a/forum_modules/sphinxfulltext/settings.py b/forum_modules/sphinxfulltext/settings.py new file mode 100755 index 00000000..c98de7b3 --- /dev/null +++ b/forum_modules/sphinxfulltext/settings.py @@ -0,0 +1,5 @@ +SPHINX_API_VERSION = 0x113 #refer to djangosphinx documentation
+SPHINX_SEARCH_INDICES=('osqa',) #a tuple of index names remember about a comma after the
+#last item, especially if you have just one :)
+SPHINX_SERVER='localhost'
+SPHINX_PORT=3312
@@ -1,5 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="django" name="Django">
+ <configuration>
+ <option name="rootFolder" value="$MODULE_DIR$" />
+ <option name="templatesFolder" value="$MODULE_DIR$/templates" />
+ <option name="settingsModule" value="settings.py" />
+ </configuration>
+ </facet>
+ </component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
diff --git a/pgfulltext/management.py b/pgfulltext/management.py deleted file mode 100644 index 46f51edc..00000000 --- a/pgfulltext/management.py +++ /dev/null @@ -1,23 +0,0 @@ -import os - -from django.db import connection, transaction -from django.conf import settings - -import forum.models - -if settings.USE_PG_FTS: - from django.db.models.signals import post_syncdb - - def setup_pgfulltext(sender, **kwargs): - if sender == forum.models_: - install_pg_fts() - - post_syncdb.connect(setup_pgfulltext) - -def install_pg_fts(): - f = open(os.path.join(os.path.dirname(__file__), '../sql_scripts/pg_fts_install.sql'), 'r') - cursor = connection.cursor() - cursor.execute(f.read()) - transaction.commit_unless_managed() - f.close() -
\ No newline at end of file |