كيف كتبت مولد الكود في PHP وماذا جاء منه

الأسباب والمشاكل التي يتعين حلها



في هذه المقالة سوف أخبرك كيف كتبت مولد أكواد في php. سأخبرك عن المسار الذي سلكه من إنشاء جداول بسيطة إلى مولد كامل إلى حد ما من كود html و css. سأقدم أمثلة على استخدامه وأعرض المشاريع المنجزة بالفعل.



يمكن استخدام PHP فقط في أحد المواد في هذا الفصل الدراسي.



بعد إعادة تسمية المشروع اللانهائيتم تسمية المشروع MelonPHP. أن يفكر الناس في الطعام عندما يقولون اسمه؟ لكن مقالتنا هنا ليست عن توليد الهذيان ، لذا دعني أخبرك عن سبب إنشائها.



كان هناك الكثير للكتابة ، لكن هذه ليست مشكلة. كانت المشكلة الرئيسية هي إخراج كود HTML من خلال PHP. سأحاول شرح المشكلة أدناه.



على سبيل المثال ، هنا إخراج النص من خلال صدى مألوف:



$text = "out text";
echo "<p>$text</p>";


يبدو بسيطًا ومباشرًا. لنأخذ مقتطفًا من رمز صديقي حيث يُنشئ جدولًا:



...
$sql = "SELECT * FROM table";$result = $conn->query($sql);
if($result->num_rows > 0) {
    echo "<b>Table table</b><br><br>";
    echo "<table border=2>";
  echo "<tr><td> name </td>"."<td> name </td>"."<td> name </td></tr>";
    while($row = $result->fetch_assoc()) {
        echo "<tr><td>".$row["name"]."</td><td>".$row["name"]."</td><td>".$row["name"]."</td></tr>";
    }
    echo "</table>";
} else {
echo "0 results";}
...


عليه رهيب يوضح الكود المشكلات التي أردت حلها:



  • وجود html في كود php ، مما يجعله أقل قابلية للقراءة في رأيي. مع ذلك ، يجب أن يحتوي ملف ياب واحد على رمز ياب واحد فقط ، في رأيي
  • لا يوجد فصل في المنطق ، كل شيء في حالة من الفوضى. أردت واجهة PHP أجمل


تجدر الإشارة إلى أنني كنت أكتب في Flutter لفترة طويلة نسبيًا وأحب حقًا الفكرة الكامنة وراءها ، المتعلقة بكتابة واجهة عن طريق بناء شجرة من عناصر واجهة المستخدم. قررت استعارة الفكرة مع العقد (الحاجيات) من هناك.



, , .



. .



:



  • UI / ( React)
  • ( div, div, div, div...)
  • UI PHP ( JS, HTML, CSS).
  • Rebuild callback , AJAX + JQuery
  • CSS ( , "width: 100px", PHP )


MelonPHP



  • ( , ) 100%, .
  • , , . ScrollView.
  • .




, PHP , . ( , Microsoft MAUI, ).



MelonPHP Node. , 2 : Generate(), static Create().



  • Generate() string — .
  • Create() — . .


abstract class Node
{
  abstract function Generate() : string;

  static function Create() ...
}


Element


Element — , .



html .



, , .



Component


, , . ( ).



( MelonPHP), , , .



abstract class Component extends Element
{
  function Initialize() ...

  abstract function Build() : Element;

  function Detach() ...
}


, ; Element. .



. ListItem, Component.



Initialize() Build().



Initialize() . .



Build() . . .



Detach() .

Build() , $Text.



Initialize() $Text .



Text(string) $Text.



$this , .


class ListItem extends Component
{
  private $Text;

  function Initialize() {
    $this->Text = "Name";
  }

  function Build() : Element {
    return Container::Create()
    ->Child(
      Text::Create()
      ->Text($this->Text)
    );
  }

  function Text(string $string) {
    $this->Text = $string;
    return $this;
  }
}


DisplayComponent


DisplayComponent — , . Display.



.



Build() Document Title(string).



DisplayComponent, Build() Document. Document — , HTML5.

BuildList(), ListItem.



BuildList() . .



- , Builder. ...

Diplay(), , c .



class ListDisplay extends DisplayComponent
{

  function Build() : Document {
    return Document::Create()
    //  
    ->Title("test page")
    ->Child($this->BuildList());
  }

  function BuildList() {
    $column = new Column;
    for($i = 0; $i < 10; $i++)
      $column->Children(
        ListItem::Create()
        ->Text("number: $i")
      );
    return $column;
  }

} ListDisplay::Display();




— .



Container




Container — , .



.



Column Row


. Child , Children .



Child Children .



Children , .



Children([Text::Create()]) Children(Text::Create())

Column — , .



CrossAlign MainAlign .





Row Column, .





Stack


Stack — , . , .





ScrollView, HorizontalScrollView, VerticalScrollView




.



HorizontalScrollView — .



VerticalScrollView — .



ScrollView — .





css .



css "background-color". php "". .



...
const BackgroundBlendMode = "background-blend-mode";
const BackgroundAttachment = "background-attachment";
const Border = "border";
const BorderSpacing = "border-spacing";
const BorderRadius = "border-radius";
const BorderImage = "border-image";
...


"34".Px. . css — Px(34). .





ThemeParameter(...). — , — /.



.



#f0f0f0.



. 20px, 15px.



. , CommaLine().


...
Container::Create()
->ThemeParameter(BackgroundColor, Hex("f0f0f0"))
->ThemeParameter(Padding, [Px(20), Px(15)]);
...


, (hover )? .





— css, media, keyframes, .



hover active.



ThemeBlock ThemeBlocks.



/ . my_container.



. : StandartModifier, HoverModifier, ActiveModifier. Parameter(...). Parameter ThemeParameter.



function GetMyTheme() : Theme {
  return Theme::Create()
  ->ThemeBlocks([
    ThemeBlock::Create()
    ->Keys("my_container")
    ->Modifiers([
      StandartModifier::Create()
      ->Parameter(BackgroundColor, Red)
      ->Parameter(Padding, [Px(10), Px(12)]),
      HoverModifier::Create()
      ->Parameter(BackgroundColor, Green),
      ActiveModifier::Create()
      ->Parameter(BackgroundColor, Blue)
    ])
  ]);
}


( css) ThemeKeys. Themes.



class TestThemeDisplay extends DisplayComponent
{

  function Build() : Document {
    return Document::Create()
    ->Themes(GetMyTheme())
    ->Child(
      Container::Create()
      ->ThemeKeys("my_container")
    );
  }

} TestThemeDisplay::Display();


.





keyframes.



keyframe, FrameBlocks.



FrameBlock.



FrameBlock Frames. , Value. ( Pr(value)) From To.



, .



, shake_text.



, .



, .



function GetMyTheme() : Theme {
  return Theme::Create()
  ->ThemeBlocks([
    ThemeBlock::Create()
    ->Keys("my_container")
    ->Modifiers([
      StandartModifier::Create()
      ->Parameter(Padding, [Px(10), Px(12)]),
      HoverModifier::Create()
      ->Parameter(BackgroundColor, Green),
      ActiveModifier::Create()
      ->Parameter(BackgroundColor, Blue)
    ]),
    ThemeBlock::Create()
    ->Keys("shake_text")
    ->Modifiers([
      StandartModifier::Create()
      ->Parameter(Color, Red)
      ->Parameter(Animation, ["shake_text_anim", ".2s", "ease-in-out", "5", "alternate-reverse"])
    ])
  ])
  ->FrameBlocks(
    FrameBlock::Create()
    ->Key("shake_text_anim")
    ->Frames([
      Frame::Create()
      ->Value(Pr(0))
      ->Parameter(Transform, Translate(0, 0)),
      Frame::Create()
      ->Value(Pr(25))
      ->Parameter(Color, Hex("ff4040"))
      ->Parameter(Filter, Blur(Px(0.5))),
      Frame::Create()
      ->Value(Pr(50))
      ->Parameter(Filter, Blur(Px(1.2))),
      Frame::Create()
      ->Value(Pr(75))
      ->Parameter(Color, Hex("ff4040"))
      ->Parameter(Filter, Blur(Px(0.5))),
      Frame::Create()
      ->Value(Pr(100))
      ->Parameter(Transform, Translate(Px(10), 0)),
    ])
  );
}


class TestThemeDisplay extends DisplayComponent
{

  function Build() : Document {
    return Document::Create()
    ->Themes(GetMyTheme())
    ->Child(
      Container::Create()
      ->ThemeKeys("my_container")
      ->Child(
        Text::Create()
        ->ThemeKeys("shake_text")
        ->Text("Error text")
      )
    );
  }

} TestThemeDisplay::Display();






2 . , . : MinWidth, MaxWidth, MinHeight, MaxHeight, .



MinWidth 800px.



MaxWidth 800px.



, — . adaptive_color.



.



.



function GetMobileTheme() : Theme {
  return Theme::Create()
  ->MinWidth(Px(800))
  ->ThemeBlocks(
    ThemeBlock::Create()
    ->Keys("adaptive_color")
    ->Modifiers(
      StandartModifier::Create()
      ->Parameter(BackgroundColor, Green)
    )
  );
}


function GetDesktopTheme() : Theme {
  return Theme::Create()
  ->MaxWidth(Px(800))
  ->ThemeBlocks(
    ThemeBlock::Create()
    ->Keys("adaptive_color")
    ->Modifiers(
      StandartModifier::Create()
      ->Parameter(BackgroundColor, Red)
    )
  );
}


class TestThemeDisplay extends DisplayComponent
{

  function Build() : Document {
    return Document::Create()
    ->Themes([
      GetMyTheme(), 
      GetDesktopTheme(), 
      GetMobileTheme()
    ])
    ->Child(
      Container::Create()
      ->ThemeKeys(["my_container", "adaptive_color"])
      ->Child(
        Text::Create()
        ->ThemeKeys("shake_text")
        ->Text("Error text")
      )
    );
  }

} TestThemeDisplay::Display();






.



DisplayComponent.



Build() Document.



class ClickerDisplay extends DisplayComponent
{

  function Build() : Element {
    return Document::Create()
    ->Title("Clicker"); 
  }

} ClickerDisplay::Display();


.



.



class ClickerDisplay extends DisplayComponent
{

  function Build() : Element {
    return Document::Create()
    ->Title("Clicker")
    ->Child(
      Column::Create()
      ->Children([
        Text::Create()
        ->Text("Pressed 0 times"),
        Button::Create()
        ->Text("Press")
      ])
    ); 
  }

} ClickerDisplay::Display();


.





ThemeParameter, .



class ClickerDisplay extends DisplayComponent
{

  function Build() : Element {
    return Document::Create()
    ->Title("Clicker")
    ->Child(
      Column::Create()
      ->ThemeParameter(Padding, Px(15))
      ->Children([
        Text::Create()
        ->ThemeParameter(PaddingBottom, Px(15))
        ->Text("Pressed 0 times"),
        Button::Create()
        ->ThemeParameter(Width, Auto)
        ->ThemeParameter(Padding, [Px(4), Px(10)])
        ->ThemeParameter(BackgroundColor, Blue)
        ->ThemeParameter(Color, White)
        ->ThemeParameter(BorderRadius, Px(4))
        ->Text("Press")
      ])
    ); 
  }

} ClickerDisplay::Display();


.





.



Initialize() TapCount.



form — Action.

Action . Action Post. , .



click_count Action. TapCount.



Initialize() Action::GetValue(name, standart_value, action_type) . 0, Post.



.



في النص ، اطبع " Press $ this-> TapCount times ".



هذا كل شيء ، جهاز نقر بسيط جاهز.



class ClickerDisplay extends DisplayComponent
{
  private $TapCount;

  function Initialize() {
    $this->TapCount = Action::GetValue("click_count", 0 /* standart value */, ActionTypes::Post);
    $this->TapCount++;
  }

  function Build() : Document {
    return Document::Create()
    ->Title("Test page")
    ->Child(
      Action::Create()
      ->Type(ActionTypes::Post)
      ->Variable("click_count", $this->TapCount)
      ->Child(
        Column::Create()
        ->ThemeParameter(Padding, Px(15))
        ->Children([
          Text::Create()
          ->ThemeParameter(PaddingBottom, Px(15))
          ->Text("Press $this->TapCount times"),
          Button::Create()
          ->ThemeParameter(Width, Auto)
          ->ThemeParameter(Padding, [Px(4), Px(10)])
          ->ThemeParameter(BackgroundColor, Blue)
          ->ThemeParameter(Color, White)
          ->ThemeParameter(BorderRadius, Px(4))
          ->Text("Press")
        ])
      )
    );
  }
} ClickerDisplay::Display();




النتيجة



تمكنت من كتابة مولد أكواد بسيط ولكنه قوي بدرجة كافية.



لقد انتقل من إنشاء جداول بسيطة إلى مولد html و css كامل ، حيث يمكنك تخطيط المشاريع بسهولة والجمع بين التخطيط والمنطق.



في هذا الإطار ، كتبت مشروعًا للدورة التدريبية (لقطات الشاشة أدناه) ، واستخدمته في الاختبار وقمت بدراسة الواجبات عليه.



لقطات من مشروع الدورة التدريبية تم إجراؤها على MelonPHP







المصادر



جيثب - MelonPHP



رفرفة



MAUI




All Articles